Return value of transferFrom
is not checked
Description
When the user calls the lock
function to transfer ERC-20 tokens to the bridge on the Ethereum network, a Lock
event is emitted. The backend observes this event or transaction to allow the user to receive funds on the Mina network.
In the current implementation, the return value of the ERC-20 transferFrom
call is not checked.
function lock(address token, string memory receipt, uint256 amount) public payable {
require(whitelistTokens[token], "Bridge: token must be in whitelist");
require(amount <= maxAmount && amount >= minAmount, "Bridge: invalid amount");
string memory name = "ETH";
if (token == address(0)) {
require(msg.value == amount, "Bridge: invalid amount");
} else {
IERC20(token).transferFrom(msg.sender, address(this), amount);
name = IERC20(token).name();
}
emit Lock(msg.sender, receipt, token, amount, name);
}
Impact
There are tokens that comply with the ERC-20 standard but are implemented in a way that does not revert when a transfer fails. In such cases, the bridge may not receive the tokens, but the Lock
event is still emitted. If a malicious user exploits this, they could inflate their funds on the Mina network and potentially drain the protocol.
Recommendations
Use the safeTransferFrom
function from OpenZepplin's SafeERC20 library to ensure that the transfer is successful and handles potential errors properly.
Remediation
This issue has been acknowledged by Sotatek, and a fix was implemented in commit 17162c1a↗.