The TokenManager
contract implements two crucial functions: tillIn()
for depositing tokens and withdraw()
for withdrawing tokens. These functions are designed to manage user balances and facilitate token transfers between users and a capital pool. However, there is a critical logical inconsistency in how these functions interact with the user's balance tracking.
The tillIn()
function is responsible for accepting token deposits from users:
The withdraw()
function allows users to withdraw their tokens:
The critical issue lies in the fact that tillIn()
does not update the userTokenBalanceMap
, which is the data structure that withdraw()
relies on to determine a user's withdrawable balance. This creates a situation where users can deposit tokens, but these deposits are not reflected in their withdrawable balance, effectively locking their funds in the contract.
Users who deposit tokens using tillIn()
will be unable to withdraw their funds using withdraw()
, as their balance in userTokenBalanceMap
remains unchanged.
The contract will accumulate user deposits without providing a mechanism for users to retrieve their funds, potentially leading to significant financial losses for users.
The severity of this issue is critical, as it directly impacts the ability of users to access their funds and compromises the fundamental operations of the contract.
Alice deposits 100 tokens using the tillIn()
function.
The tokens are successfully transferred to the capital pool, and the TillIn
event is emitted.
Alice checks her balance in the contract by calling userTokenBalanceMap[alice][tokenAddress][TokenBalanceType.Available]
, which returns 0.
Alice attempts to withdraw her 100 tokens using the withdraw()
function.
The withdrawal fails because claimAbleAmount
is 0, as userTokenBalanceMap
was never updated during the deposit.
Alice's 100 tokens are now locked in the contract with no mechanism to withdraw them.
Manual review
To resolve this critical issue, the tillIn()
function should be updated to properly track user balances in the userTokenBalanceMap
. Here's the recommended fix:
This change ensures that when a user deposits tokens, their balance in userTokenBalanceMap
is updated accordingly. This will allow the withdraw()
function to correctly determine the user's withdrawable balance, enabling users to access their deposited funds.
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.