The withdrawAllFailedCredits function is designed to allow users to withdraw ETH credits that failed to transfer during the normal payout process.
Users should only be able to withdraw their own failed credits, maintaining the integrity of the marketplace's accounting system.
However, the function contains a critical logic error: it uses the _receiver parameter to determine the withdrawal amount but then resets msg.sender's balance and sends the funds to msg.sender.
This vulnerability allows an attacker to:
Pass any victim's address as _receiver parameter
Withdraw the victim's credit balance to themselves
Leave the victim's balance unchanged in the mapping
Enable the victim to also withdraw the same credits (double-spend)
Likelihood:
The attack requires no special permissions, setup, or prerequisites beyond knowing addresses with credits
The attacker needs only to identify addresses with failed credits (often visible in transaction history)
The function is externally callable by any address at any time
Impact:
Direct theft of all failed transfer credits from any user in the system
Victim's balance remains unchanged in the contract, creating a double-spend vulnerability
Protocol becomes insolvent as liabilities exceed available funds
Complete breakdown of the failed credits accounting system
Attack Walkthrough:
Victim has 5 ETH in failed credits (from a previous failed refund)
Attacker calls withdrawAllFailedCredits(victimAddress)
Contract reads victim's 5 ETH balance but resets attacker's balance (which was 0)
Attacker receives 5 ETH they never owned
Victim's balance remains at 5 ETH in the contract
Victim can still withdraw their 5 ETH
Marketplace loses 10 ETH total from only 5 ETH of legitimate credits
Explanation of the Mitigation:
Simplifies the function by removing the unnecessary parameter entirely. Users can only withdraw their own credits, eliminating any possibility of confusion or exploitation.
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.
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.