Lucene search

K
code423n4Code4renaCODE423N4:2023-05-BASE-FINDINGS-ISSUES-39
HistoryJun 02, 2023 - 12:00 a.m.

_initiateBridgeERC20() does not check if _remoteToken is valid. When the message send to L2, it will cause user lossing funds in L1

2023-06-0200:00:00
Code4rena
github.com
7
vulnerability impact tokens poc mitigation

Lines of code

Vulnerability details

Impact

_initiateBridgeERC20() does not check if _remoteToken is valid. When the message send to L2, it will cause user lossing funds in L1

Proof of Concept

As we can see, the_initiateBridgeERC20 just check _isOptimismMintableERC20(_localToken),if valid ,it will call finalizeBridgeERC20 in L2.

    function _initiateBridgeERC20(
        address _localToken,
        address _remoteToken,
        address _from,
        address _to,
        uint256 _amount,
        uint32 _minGasLimit,
        bytes memory _extraData
    ) internal {
        if (_isOptimismMintableERC20(_localToken)) {//@audit
            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 the correct events. By default this will be ERC20BridgeInitiated, but child
        // contracts may override this function in order to emit legacy events as well.
        _emitERC20BridgeInitiated(_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
        );
    }

However, the L2 will check _localToken(L2 's localToken is L1’s remoteToken). if _localToken is invalid, it will revert.It will cause user lossing funds in L1

    function finalizeBridgeERC20(
        address _localToken,
        address _remoteToken,
        address _from,
        address _to,
        uint256 _amount,
        bytes calldata _extraData
    ) public onlyOtherBridge {
        if (_isOptimismMintableERC20(_localToken)) {//@audit check the _localToken from L1, but L1 does not check
            require(
                _isCorrectTokenPair(_localToken, _remoteToken),
                "StandardBridge: wrong remote token for Optimism Mintable ERC20 local token"
            );

            OptimismMintableERC20(_localToken).mint(_to, _amount);
        } else {
            deposits[_localToken][_remoteToken] = deposits[_localToken][_remoteToken] - _amount;
            IERC20(_localToken).safeTransfer(_to, _amount);
        }

        // Emit the correct events. By default this will be ERC20BridgeFinalized, but child
        // contracts may override this function in order to emit legacy events as well.
        _emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);
    }

Tools Used

vs code

Recommended Mitigation Steps

Adding check if _remoteToken is valid in L1

Assessed type

Other


The text was updated successfully, but these errors were encountered:

All reactions