Unchecked transferFrom
return value in deposit
Description
The bridge handles deposits by transferring an amount of USDC from the sender and emitting a corresponding event.
// An external function anyone can call to deposit usdc into the bridge.
// A deposit event will be emitted crediting the L1 with the usdc.
function deposit(uint64 usdc) external whenNotPaused nonReentrant {
address user = msg.sender;
emit Deposit(DepositEvent({ user: user, usdc: usdc }));
usdcToken.transferFrom(user, address(this), usdc);
}
The return value of the transferFrom
call is not checked. Although USDC on Arbitrum will currently revert when the transfer is not permitted (e.g., if the approval amount is insufficient), this behavior is not required by the ERC-20 specification. Instead, transferFrom
must return a boolean indicating whether it was successful.
Impact
If this logic were reused for other token types, it could potentially result in a loss of funds. Users would be able to arbitrarily call deposit
and cause the corresponding event to be emitted.
Recommendations
Consider checking the return value as well, or use the SafeERC20 OpenZeppelin library and its safeTransferFrom
function.
Remediation
This issue has been acknowledged by Hyperliquid, and a fix was implemented in commit 57df1c10↗.