TokenManager doesn't account for funds that were already withdrawn from the contract, leading to the ability for anyone with any amount of tokens to withdraw the entire fund by repeatedly calling withdraw
until the CapitalPool
is completely depleted.
TokenManager is the contract that tracks users' balances in different categories (like referral/taxes, etc.), and it has the mapping userTokenBalanceMap
(https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/storage/TokenManagerStorage.sol#L19-L20) which is used for this purpose. However, the problem arises from the transfer logic itself. The contract has a withdraw
function that allows users to withdraw their tokens (https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/TokenManager.sol#L137-L189), but after withdrawal, the claimed tokens are not subtracted from userTokenBalanceMap
, which means we can call the withdraw
function until the CapitalPool
is emptied entirely.
Any user with the smallest amount recorded in userTokenBalanceMap
can steal the entire CapitalPool
supply.
Output:
BALANCE ON TOKENMANAGER BEFORE WITHDRAW - 150000000000000
BALANCE BEFORE 99999999983825000000000000
BALANCE AFTER 99999999984125000000000000
BALANCE ON TOKENMANAGER AFTER WITHDRAW - 150000000000000
Foundry.
Substract withdrawn tokens from userTokenBalanceMap
mapping to fix this error.
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.