Normal Behavior: The withdrawAllFailedCredits function should only allow the caller (msg.sender) to retrieve their own credited funds.
Specific Issue: The function incorrectly uses an external parameter _receiver to determine the credit balance to withdraw, but then unconditionally transfers that amount to and clears the balance of msg.sender. An attacker can pass any victim's address to steal their locked funds.
Likelihood:
This bug is in the logic of the withdrawal function itself and is directly callable by any external user.
An attacker only needs to know an address with a non-zero credit balance (which can be observed on-chain).
Impact:
Direct and permanent loss of user funds.
Breach of asset confidentiality and integrity.
This PoC demonstrates how an Attacker (BIDDER_2) steals the credited funds of a Victim (BIDDER_1) by simply using the victim's address as the function parameter. This occurs because the function uses _receiver to read the amount but msg.sender to execute the transfer.
The function must be updated to exclusively use msg.sender to both read the balance and perform the payout. This ensures the withdrawal is correctly gated by who calls the function (the owner of the credit). We remove the external parameter and update all internal references to use msg.sender.
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.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.