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 }