用户从L2StandardBridge.sol 提现
function withdraw(
address _l2Token,
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) external payable virtual onlyEOA {
_initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);
}
function _initiateWithdrawal(
address _l2Token,
address _from,
address _to,
uint256 _amount,
uint32 _minGasLimit,
bytes memory _extraData
) internal {
if (_l2Token == Predeploys.LEGACY_ERC20_ETH) {
_initiateBridgeETH(_from, _to, _amount, _minGasLimit, _extraData);
} else {
address l1Token = OptimismMintableERC20(_l2Token).l1Token();
_initiateBridgeERC20(_l2Token, l1Token, _from, _to, _amount, _minGasLimit, _extraData);
}
}
function _initiateBridgeERC20(
address _localToken,
address _remoteToken,
address _from,
address _to,
uint256 _amount,
uint32 _minGasLimit,
bytes memory _extraData
) internal {
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 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
);
}