At TokenManager.sol contract, the withdraw() function does not delete the state responsible for the funds accounting. Thus users can simply call it multiple times and withdraw value that is not theirs.
🚧 Note ⚠️ The code has another issue, doesnt approve to
CapitalPoolbefore transfer with tokens different than WETH, so withdraw always reverts, once that fixed, run this poc and see that this issue also exists and has different root source. To fix it add this line:ICapitalPool(capitalPoolAddr).approve(_tokenAddress);, here. I've sent that report separately, this report is not about this issue please do not include this issue as a duplicate of that one, this issue is about drainning the pool due to bad accounting.
Paste this test in the PreMarkets.t.sol file, import import "forge-std/console.sol";, and run forge test --mt "test_stealFundsWithdraw":
Reset the value on the mapping each time a user withdraws their funds like so:
It is better to do it after the functions' cheks to follow the safety standanrd of check effects interactions. Should be around here.
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.