github.com/klaytn/klaytn@v1.12.1/contracts/bridge/BridgeTransferERC20.sol (about)

     1  // Copyright 2019 The klaytn Authors
     2  // This file is part of the klaytn library.
     3  //
     4  // The klaytn library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The klaytn library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  pragma solidity 0.5.6;
    18  
    19  import "../externals/openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
    20  import "../externals/openzeppelin-solidity/contracts/token/ERC20/ERC20Mintable.sol";
    21  import "../externals/openzeppelin-solidity/contracts/token/ERC20/ERC20Burnable.sol";
    22  
    23  import "../sc_erc20/IERC20BridgeReceiver.sol";
    24  import "./BridgeTransfer.sol";
    25  
    26  
    27  contract BridgeTransferERC20 is BridgeTokens, IERC20BridgeReceiver, BridgeTransfer {
    28      // handleERC20Transfer sends the token by the request.
    29      function handleERC20Transfer(
    30          bytes32 _requestTxHash,
    31          address _from,
    32          address _to,
    33          address _tokenAddress,
    34          uint256 _value,
    35          uint64 _requestedNonce,
    36          uint64 _requestedBlockNumber,
    37          bytes memory _extraData
    38      )
    39          public
    40          onlyOperators
    41      {
    42          _lowerHandleNonceCheck(_requestedNonce);
    43  
    44          if (!_voteValueTransfer(_requestedNonce)) {
    45              return;
    46          }
    47  
    48          _setHandledRequestTxHash(_requestTxHash);
    49  
    50          handleNoncesToBlockNums[_requestedNonce] = _requestedBlockNumber;
    51          _updateHandleNonce(_requestedNonce);
    52  
    53          emit HandleValueTransfer(
    54              _requestTxHash,
    55              TokenType.ERC20,
    56              _from,
    57              _to,
    58              _tokenAddress,
    59              _value,
    60              _requestedNonce,
    61              lowerHandleNonce,
    62              _extraData
    63          );
    64  
    65          if (modeMintBurn) {
    66              require(ERC20Mintable(_tokenAddress).mint(_to, _value), "handleERC20Transfer: mint failed");
    67          } else {
    68              require(IERC20(_tokenAddress).transfer(_to, _value), "handleERC20Transfer: transfer failed");
    69          }
    70      }
    71  
    72      // _requestERC20Transfer requests transfer ERC20 to _to on relative chain.
    73      function _requestERC20Transfer(
    74          address _tokenAddress,
    75          address _from,
    76          address _to,
    77          uint256 _value,
    78          uint256 _feeLimit,
    79          bytes memory _extraData
    80      )
    81          internal
    82          onlyRegisteredToken(_tokenAddress)
    83          onlyUnlockedToken(_tokenAddress)
    84      {
    85          require(isRunning, "stopped bridge");
    86          require(_value > 0, "zero msg.value");
    87  
    88          uint256 fee = _payERC20FeeAndRefundChange(_from, _tokenAddress, _feeLimit);
    89  
    90          if (modeMintBurn) {
    91              ERC20Burnable(_tokenAddress).burn(_value);
    92          }
    93  
    94          emit RequestValueTransfer(
    95              TokenType.ERC20,
    96              _from,
    97              _to,
    98              _tokenAddress,
    99              _value,
   100              requestNonce,
   101              fee,
   102              _extraData
   103          );
   104          requestNonce++;
   105      }
   106  
   107      // onERC20Received function of ERC20 token for 1-step deposits to the Bridge.
   108      function onERC20Received(
   109          address _from,
   110          address _to,
   111          uint256 _value,
   112          uint256 _feeLimit,
   113          bytes memory _extraData
   114      )
   115          public
   116      {
   117          _requestERC20Transfer(msg.sender, _from, _to, _value, _feeLimit, _extraData);
   118      }
   119  
   120      // requestERC20Transfer requests transfer ERC20 to _to on relative chain.
   121      function requestERC20Transfer(
   122          address _tokenAddress,
   123          address _to,
   124          uint256 _value,
   125          uint256 _feeLimit,
   126          bytes memory _extraData
   127      )
   128          public
   129      {
   130          require(IERC20(_tokenAddress).transferFrom(msg.sender, address(this), _value.add(_feeLimit)), "requestERC20Transfer: transferFrom failed");
   131          _requestERC20Transfer(_tokenAddress, msg.sender, _to, _value, _feeLimit, _extraData);
   132      }
   133  
   134  
   135      // setERC20Fee sets the fee of the token transfer.
   136      function setERC20Fee(address _token, uint256 _fee, uint64 _requestNonce)
   137          external
   138          onlyOperators
   139      {
   140          if (!_voteConfiguration(_requestNonce)) {
   141              return;
   142          }
   143          _setERC20Fee(_token, _fee);
   144      }
   145  }