Normal behavior: The withdrawAllFailedCredits function is intended to allow users to withdraw their own pending credits that accumulated due to failed ETH transfers. Each user should only be able to withdraw their own credits, and those credits should be properly cleared after withdrawal.
Issue: The function takes an arbitrary _receiver argument but uses msg.sender to zero out credits. This mismatch allows a malicious caller to withdraw another user’s credits while leaving the victim’s credit balance intact in storage. This enables repeated theft of all ETH from the contract.
Likelihood:
Any time a failed ETH transfer occurs (e.g., when sending to a contract without a payable fallback), credits are stored in failedTransferCredits.
Whenever such credits exist, an attacker can call withdrawAllFailedCredits(victim) to redirect funds to themselves.
Impact:
Attackers can steal all ETH from the contract.
Victims’ balances remain unchanged in storage, leaving the system in an inconsistent state.
Run the following test:
Change withdrawAllFailedCredits as below:
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.