userTokenBalanceMap
is never set 0 after withdrawal allowing users to steal funds.
TokenManager::withdraw(...)
function checks the claimAbleAmount
for the user and if it's greater than zero, it allows the user to withdraw that amount. However, after the withdrawal, the claimAbleAmount
is not reset to zero. This means that if the withdraw function is called again, the user could withdraw the same amount again, even though they've already claimed their tokens.
Let's consider an example where Bob has 100 tokens in his refund:
Bob calls the withdraw function to withdraw all his 100 tokens. The claimAbleAmount
for Bob is now 100 tokens.
The withdraw function checks if claimAbleAmount
is greater than zero, which it is, so it allows the withdrawal.
Bob successfully withdraws 100 tokens. However, the claimAbleAmount
is not reset to zero after the withdrawal.
Now, Bob calls the withdraw function again. Even though he has already withdrawn all his tokens, the claimAbleAmount
is still 100.
The withdraw function again checks if claimAbleAmount
is greater than zero, which it is, so it allows another withdrawal.
Bob is now able to withdraw another 100 tokens, even though he should only have been able to withdraw 100 in total. He has effectively doubled his withdrawal due to the bug.
Steal of funds.
Manual review.
Valid critical severity finding, the lack of clearance of the `userTokenBalanceMap` mapping allows complete draining of the CapitalPool contract. Note: This would require the approval issues highlighted in other issues to be fixed first (i.e. wrong approval address within `_transfer` and lack of approvals within `_safe_transfer_from` during ERC20 withdrawals)
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.