Some tokens do not implement the ERC20 standard properly but are still accepted by most code that accepts ERC20 tokens. For example Tether (USDT)'s transfer() and transferFrom() functions do not return booleans as the specification requires, and instead have no return value. When these sorts of tokens are cast to ERC20Upgradeable, their function signatures do not match and therefore the calls made will revert.
Impact
The code as currently implemented does not handle these sorts of tokens properly when they're deposited or withdrawn. Tether cannot be deposited because depositing requires a cast and a call to transferFrom() which will revert. If a token has a different signature for transfer() but the correct one for transferFrom() the user's tokens will be stuck.
Lines of code
https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#L120-L124 https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#L306-L308 https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#L206
Vulnerability details
Some tokens do not implement the ERC20 standard properly but are still accepted by most code that accepts ERC20 tokens. For example Tether (USDT)'s
transfer()
andtransferFrom()
functions do not return booleans as the specification requires, and instead have no return value. When these sorts of tokens are cast toERC20Upgradeable
, their function signatures do not match and therefore the calls made will revert.Impact
The code as currently implemented does not handle these sorts of tokens properly when they're deposited or withdrawn. Tether cannot be deposited because depositing requires a cast and a call to
transferFrom()
which will revert. If a token has a different signature fortransfer()
but the correct one fortransferFrom()
the user's tokens will be stuck.Proof of Concept
https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#L120-L124
https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#L306-L308
https://github.com/skalenetwork/ima-c4-audit/blob/11d6a6ae5bf16af552edd75183791375e501915f/contracts/mainnet/DepositBoxes/DepositBoxERC20.sol#L206
Tools Used
Code inspection
Recommended Mitigation Steps
Use OpenZeppelin’s
SafeERC20Upgradeable
'ssafeTransfer()
andsafeTransferFrom()
instead