Skip to content
This repository has been archived by the owner on May 26, 2023. It is now read-only.

Latest commit

 

History

History
79 lines (68 loc) · 2.76 KB

031.md

File metadata and controls

79 lines (68 loc) · 2.76 KB

ustas

medium

Zero address check in the StandardBridge._initiateBridgeERC20() function

Summary

StandardBridge allows ERC20 tokens to be sent to the zero address.

Vulnerability Detail

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.

Impact

Inexecutable transactions; will lead to a lock of funds on the bridge.

Code Snippet

https://github.com/sherlock-audit/2023-01-optimism/blob/main/optimism/packages/contracts-bedrock/contracts/universal/StandardBridge.sol#L385-L436

Tool used

Manual Review, VSCodium

Recommendation

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
    );
}