ustas
medium
StandardBridge
allows ERC20 tokens to be sent to the zero address.
The StandardBridge._initiateBridgeERC20()
function does not check _to != address(0)
.
OpenZeppelin's implementation of ERC20 doesn't allow transfer to zero address. Thus, all transfers to/from L2 will always be reverted.
Inexecutable transactions; will lead to a lock of funds on the bridge.
Manual Review, VSCodium
Add a check to the function.
/**
* @notice Sends ERC20 tokens to a receiver's address on the other chain.
*
* @param _localToken Address of the ERC20 on this chain.
* @param _remoteToken Address of the corresponding token on the remote chain.
* @param _to Address of the receiver.
* @param _amount Amount of local tokens to deposit.
* @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.
* @param _extraData Extra data to be sent with the transaction. Note that the recipient will
* not be triggered with this data, but it will be emitted and can be used
* to identify the transaction.
*/
function _initiateBridgeERC20(
address _localToken,
address _remoteToken,
address _from,
address _to,
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) internal {
require(_to != address(0), "StandardBridge: receiver cannot be zero address");
if (_isOptimismMintableERC20(_localToken)) {
require(
_isCorrectTokenPair(_localToken, _remoteToken),
"StandardBridge: wrong remote token for Optimism Mintable ERC20 local token"
);
OptimismMintableERC20(_localToken).burn(_from, _amount);
} else {
IERC20(_localToken).safeTransferFrom(_from, address(this), _amount);
deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] + _amount;
}
emit ERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);
MESSENGER.sendMessage(
address(OTHER_BRIDGE),
abi.encodeWithSelector(
this.finalizeBridgeERC20.selector,
// Because this call will be executed on the remote chain, we reverse the order of
// the remote and local token addresses relative to their order in the
// finalizeBridgeERC20 function.
_remoteToken,
_localToken,
_from,
_to,
_amount,
_extraData
),
_minGasLimit
);
}