From a4453539850308832bfcb872b5967c83848719e2 Mon Sep 17 00:00:00 2001 From: bendanzhentan <455462586@qq.com> Date: Fri, 24 Nov 2023 10:18:26 +0800 Subject: [PATCH] contracts: add function "withdrawFeeToL1" --- contracts/src/L2StandardBridgeBot.sol | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/contracts/src/L2StandardBridgeBot.sol b/contracts/src/L2StandardBridgeBot.sol index 043c4f1..79f8b50 100644 --- a/contracts/src/L2StandardBridgeBot.sol +++ b/contracts/src/L2StandardBridgeBot.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.20; import { Ownable } from "openzeppelin-contracts/contracts/access/Ownable.sol"; import { IERC20 } from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; +// See also https://github.com/bnb-chain/opbnb/blob/9505ae88d0ec8f593ee036284c9a13672526a232/packages/contracts-bedrock/contracts/L2/L2StandardBridge.sol#L20 interface IL2StandardBridge { function withdrawTo( address _l2Token, @@ -51,6 +52,7 @@ contract L2StandardBridgeBot is Ownable { require(approveSuccess, "BEP20 withdrawal: approve failed"); bool transferSuccess = l2Token.transferFrom(msg.sender, address(this), _amount); require(transferSuccess, "BEP20 withdrawal: transferFrom failed"); + L2_STANDARD_BRIDGE.withdrawTo{value: 0}(_l2Token, _to, _amount, _minGasLimit, _extraData); } @@ -66,12 +68,30 @@ contract L2StandardBridgeBot is Ownable { withdrawTo(_l2Token, msg.sender, _amount, _minGasLimit, _extraData); } - // withdrawFee withdraw the delegation fee vault to _recipient address, only owner can call this function. + // withdrawFee withdraw the delegation fee vault to _recipient address on L2, only owner can call this function. function withdrawFee(address _recipient) external onlyOwner { (bool sent, ) = _recipient.call{ value: address(this).balance }(""); require(sent, "Failed to send Ether"); } + // withdrawFeeToL1 withdraw the delegation fee vault to _recipient address on L1, only owner can call this function. + // + // NOTE: Since the `withdrawTo` function is defined as external and `_extraData` is `bytes calldata`, the + // `_extraData` cannot be mock from `bytes memory` by the caller. See also https://github.com/ethereum/solidity/issues/12778 + function withdrawFeeToL1(address _recipient, bytes calldata _extraData) external onlyOwner { + uint256 _balance = address(this).balance; + require(_balance > delegationFee, "fee vault balance is insufficient to pay the required amount"); + + uint256 _amount = _balance - delegationFee; + this.withdrawTo{ value: _balance }( + LEGACY_ERC20_ETH, + _recipient, + _amount, + 160000 , // constant acceptable minGasLimit is fine + _extraData + ); + } + // setDelegationFee set the delegation fee, only owner can call this function. function setDelegationFee(uint256 _delegationFee) external onlyOwner { delegationFee = _delegationFee;