The withdraw function in the contract directly uses IERC20(token).transfer(recipient, amount); instead of SafeERC20.safeTransfer. This can result in silent failures for ERC-20 tokens that do not return a boolean value, potentially locking funds.
Some ERC-20 tokens do not adhere strictly to the ERC-20 standard and may:
Return no value at all, causing silent failures. eg USDT, BNB
Revert instead of returning false, making it unclear whether the transfer was successful. eg AAVE
Use non-standard implementations that require handling failures explicitly.
Using IERC20(token).transfer(...) directly assumes all tokens follow the standard correctly. However, some tokens (such as USDT) do not return a boolean, leading to potential issues where:
The transfer appears to succeed, but funds are not actually sent.
The _balances and _totalValue state variables are updated incorrectly, desynchronizing internal accounting and most likely locking of those assets as the contract as the state update reflects they have been withdrawn.
If a transfer fails silently, the contract updates _balances[token] and _totalValue even though no actual transfer occurred, leading to incorrect balances.
Users may permanently lose access to their funds due to the discrepancy between the recorded balance and the actual token holdings.
Attackers may exploit this flaw to drain contract balances by forcing silent failures on specific tokens.
Manual review.
Use OpenZeppelin’s SafeERC20 library and replace transfer with safeTransfer:
This ensures that token transfers do not silently fail and revert properly if a transfer is unsuccessful.
LightChaser Low-60
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.