Because the withdraw
function does not reset the corresponding userTokenBalanceMap[_msgSender()][_tokenAddress][_tokenBalanceType]
to 0, msg.sender
is able to repeatedly call it to claim the same claimAbleAmount
each time. This allows such msg.sender
to steal multiples of such claimAbleAmount
, other than his first claim of such claimAbleAmount
, that do not belong to him from the capital pool.
Calling the following withdraw
function executes uint256 claimAbleAmount = userTokenBalanceMap[_msgSender()][_tokenAddress][_tokenBalanceType]
in which such claimAbleAmount
is then claimed by msg.sender
through either the payable(msg.sender).transfer
or _safe_transfer_from
function call. However, since such userTokenBalanceMap[_msgSender()][_tokenAddress][_tokenBalanceType]
is not reset to 0, such msg.sender
can repeatedly call the withdraw
function to claim the same claimAbleAmount
each time until the capital pool's token balance of the _tokenAddress
is depleted.
After the corresponding msg.sender
repeatedly calls the withdraw
function to claim the same claimAbleAmount
each time, he has stolen multiples of such claimAbleAmount
, other than his first claim of such claimAbleAmount
, that do not belong to him from the capital pool.
Manual Review
The withdraw
function can be updated to reset the corresponding userTokenBalanceMap[_msgSender()][_tokenAddress][_tokenBalanceType]
to 0 before transferring the corresponding claimAbleAmount
to msg.sender
.
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.