github.com/klaytn/klaytn@v1.12.1/contracts/bridge/BridgeTransferERC721.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/ERC721/IERC721.sol";
    20  import "../externals/openzeppelin-solidity/contracts/token/ERC721/ERC721MetadataMintable.sol";
    21  import "../externals/openzeppelin-solidity/contracts/token/ERC721/ERC721Burnable.sol";
    22  
    23  import "../sc_erc721/IERC721BridgeReceiver.sol";
    24  import "./BridgeTransfer.sol";
    25  
    26  
    27  contract BridgeTransferERC721 is BridgeTokens, IERC721BridgeReceiver, BridgeTransfer {
    28      // handleERC721Transfer sends the ERC721 by the request.
    29      function handleERC721Transfer(
    30          bytes32 _requestTxHash,
    31          address _from,
    32          address _to,
    33          address _tokenAddress,
    34          uint256 _tokenId,
    35          uint64 _requestedNonce,
    36          uint64 _requestedBlockNumber,
    37          string memory _tokenURI,
    38          bytes memory _extraData
    39      )
    40          public
    41          onlyOperators
    42      {
    43          _lowerHandleNonceCheck(_requestedNonce);
    44  
    45          if (!_voteValueTransfer(_requestedNonce)) {
    46              return;
    47          }
    48  
    49          _setHandledRequestTxHash(_requestTxHash);
    50  
    51          handleNoncesToBlockNums[_requestedNonce] = _requestedBlockNumber;
    52          _updateHandleNonce(_requestedNonce);
    53  
    54          emit HandleValueTransfer(
    55              _requestTxHash,
    56              TokenType.ERC721,
    57              _from,
    58              _to,
    59              _tokenAddress,
    60              _tokenId,
    61              _requestedNonce,
    62              lowerHandleNonce,
    63              _extraData
    64          );
    65  
    66          if (modeMintBurn) {
    67              require(ERC721MetadataMintable(_tokenAddress).mintWithTokenURI(_to, _tokenId, _tokenURI), "mint failed");
    68          } else {
    69              IERC721(_tokenAddress).transferFrom(address(this), _to, _tokenId);
    70          }
    71      }
    72  
    73      // _requestERC721Transfer requests transfer ERC721 to _to on relative chain.
    74      function _requestERC721Transfer(
    75          address _tokenAddress,
    76          address _from,
    77          address _to,
    78          uint256 _tokenId,
    79          bytes memory _extraData
    80      )
    81          internal
    82          onlyRegisteredToken(_tokenAddress)
    83          onlyUnlockedToken(_tokenAddress)
    84      {
    85          require(isRunning, "stopped bridge");
    86          (bool success, bytes memory uri) = _tokenAddress.call(abi.encodePacked(ERC721Metadata(_tokenAddress).tokenURI.selector, abi.encode(_tokenId)));
    87          if (success == false) {
    88              uri = "";
    89          }
    90          if (modeMintBurn) {
    91              ERC721Burnable(_tokenAddress).burn(_tokenId);
    92          }
    93          emit RequestValueTransferEncoded(
    94              TokenType.ERC721,
    95              _from,
    96              _to,
    97              _tokenAddress,
    98              _tokenId,
    99              requestNonce,
   100              0,
   101              _extraData,
   102              2,
   103              abi.encode(string(uri))
   104          );
   105          requestNonce++;
   106      }
   107  
   108      // onERC721Received function of ERC721 token for 1-step deposits to the Bridge
   109      function onERC721Received(
   110          address _from,
   111          uint256 _tokenId,
   112          address _to,
   113          bytes memory _extraData
   114      )
   115          public
   116      {
   117          _requestERC721Transfer(msg.sender, _from, _to, _tokenId, _extraData);
   118      }
   119  
   120      // requestERC721Transfer requests transfer ERC721 to _to on relative chain.
   121      function requestERC721Transfer(
   122          address _tokenAddress,
   123          address _to,
   124          uint256 _tokenId,
   125          bytes memory _extraData
   126      )
   127          public
   128      {
   129          IERC721(_tokenAddress).transferFrom(msg.sender, address(this), _tokenId);
   130          _requestERC721Transfer(_tokenAddress, msg.sender, _to, _tokenId, _extraData);
   131      }
   132  }