Bid Beasts

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

Failed credits withdrawal function allows theft of all contract funds

Description:

The withdrawAllFailedCredits() function contains a critical vulnerability where it reads the balance of one user (_receiver) (parameter is controled by attacker) but resets the balance of another user (msg.sender) and sends funds to msg.sender. This creates a severe vulnerability where any user can drain all ETH from the contract by specifying other users' addresses as the _receiver parameter while receiving the funds themselves.

Attack path:

  1. Attacker calls withdrawAllFailedCredits(victimAddress) where victimAddress has accumulated failed ETH

  2. The function reads amount = failedTransferCredits[victimAddress] (victim's balance)

  3. The function incorrectly resets failedTransferCredits[msg.sender] = 0 (attacker's balance, not victim's)

  4. The function sends amount ETH to payable(msg.sender) (attacker receives funds)

  5. Victim's balance failedTransferCredits[victimAddress] remains unchanged

  6. Attacker can repeat this process indefinitely to drain all ETH from the contract

Impact:

Complete theft of the entire contract balance (failed transfer ETH + fees)

Recommended Mitigation:

Fix the function that msg.sender can set different receiver address, if msg.sender could not receive ETH

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

Lead Judging Commences

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