github.com/amazechain/amc@v0.1.3/contracts/deposit/FUJI/staking.sol (about)

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity ^0.8.17;
     3  
     4  import "@openzeppelin/contracts@v4.9.0/access/Ownable.sol";
     5  import "@openzeppelin/contracts@v4.9.0/token/ERC721/ERC721.sol";
     6  import "@openzeppelin/contracts@v4.9.0/token/ERC721/IERC721Receiver.sol";
     7  import "@openzeppelin/contracts@v4.9.0/token/ERC721/IERC721.sol";
     8  import "@openzeppelin/contracts-upgradeable@v4.9.0/proxy/utils/Initializable.sol";
     9  import "./IDeposit.sol";
    10  
    11  contract StakingFUJI is IDeposit, IERC721Receiver, Ownable {
    12      IERC721 token;
    13      mapping(uint256 => bool) T200NFT;
    14      mapping(uint256 => bool) T800NFT;
    15      mapping(uint256 => bool) T2000NFT;
    16  
    17      mapping(address => uint256) depoistNFT;
    18      mapping(address => uint256) depositExpire;
    19  
    20      mapping(uint256 => address) withdrawIDToAddress;
    21      mapping(address => uint256) withdrawAddressToID;
    22      // mapping(address => uint256) withdrawNFT;
    23  
    24      constructor(address fujiAddr, address fujiAdminAddress) Ownable() {
    25          token = IERC721(fujiAddr);
    26          token.setApprovalForAll(fujiAdminAddress, true);
    27      }
    28  
    29      function addT200TokendIDs(uint256[] calldata T200TokenIDs) public  virtual  onlyOwner {
    30          for (uint i = 0; i < T200TokenIDs.length; i++) {
    31              T200NFT[T200TokenIDs[i]] = true;
    32          }
    33      }
    34  
    35      function addT800TokendIDs(uint256[] calldata T800TokenIDs) public  virtual  onlyOwner {
    36          for (uint i = 0; i < T800TokenIDs.length; i++) {
    37              T800NFT[T800TokenIDs[i]] = true;
    38          }
    39      }
    40  
    41      function addT2000TokendIDs(uint256[] calldata T2000TokenIDs) public  virtual  onlyOwner {
    42          for (uint i = 0; i < T2000TokenIDs.length; i++) {
    43              T2000NFT[T2000TokenIDs[i]] = true;
    44          }
    45      }
    46  
    47      function supportsInterface(
    48          bytes4 interfaceId
    49      ) external pure returns (bool) {
    50          return
    51          interfaceId == type(IDeposit).interfaceId ||
    52          interfaceId == type(IERC721Receiver).interfaceId;
    53      }
    54  
    55      function deposit(
    56          bytes calldata pubkey,
    57          bytes calldata signature,
    58          uint256 tokenID
    59      ) external {
    60          require(pubkey.length == 48, "Staking: invalid public key");
    61          require(signature.length == 96, "Staking: invalid signature");
    62          require(
    63              T200NFT[tokenID]  || T800NFT[tokenID] || T2000NFT[tokenID],
    64              "Staking: not allowed token"
    65          );
    66          require(depoistNFT[msg.sender] == tokenID, "Staking: tokenID do not have transfed");
    67  
    68          depositExpire[msg.sender] = block.timestamp + 90 days;
    69          emit DepositEvent(pubkey, nftToAmount(tokenID), signature);
    70      }
    71  
    72      function withdraw() external {
    73  
    74          uint256 tokenID = depoistNFT[msg.sender];
    75  
    76          require(tokenID > 0, "Staking: not deposited");
    77          require(
    78              depositExpire[msg.sender] <= block.timestamp,
    79              "Staking: token is locked"
    80          );
    81          require(
    82              token.ownerOf(tokenID) == address(this),
    83              "Staking: Insuficient Allowance"
    84          );
    85  
    86          withdrawIDToAddress[tokenID] = msg.sender;
    87          withdrawAddressToID[msg.sender] = tokenID;
    88          // withdrawNFT[msg.sender] = tokenID;
    89          delete depoistNFT[msg.sender];
    90          delete depositExpire[msg.sender];
    91  
    92          emit WithdrawnEvent(nftToAmount(tokenID));
    93      }
    94  
    95      function depositsOf(address account) external view returns (uint256) {
    96          if (depositExpire[account] == 0) {
    97              return 0;
    98          }
    99          return depoistNFT[account];
   100      }
   101  
   102      function depositsOfBalance(address account) external view returns (uint256) {
   103          if (depositExpire[account] == 0) {
   104              return 0;
   105          }
   106          return nftToAmount(depoistNFT[account]);
   107      }
   108      function transferOf(address account) external view returns (uint256) {
   109          return depoistNFT[account];
   110      }
   111  
   112      function transferOfBalance(address account) external view returns (uint256) {
   113          return nftToAmount(depoistNFT[account]);
   114      }
   115  
   116      function depositUnlockingTimestamp(
   117          address account
   118      ) external view returns (uint256) {
   119          return depositExpire[account];
   120      }
   121  
   122      function withdrawOf(address account) external view returns (uint256) {
   123          return withdrawAddressToID[account];
   124      }
   125  
   126  
   127      function nftToAmount(uint256 id) internal view returns (uint256) {
   128          if (T200NFT[id] == true) {
   129              return 200 ether;
   130          }
   131  
   132          if (T800NFT[id] == true)  {
   133              return 800 ether;
   134          }
   135  
   136          if (T2000NFT[id] == true)  {
   137              return 2000 ether;
   138          }
   139  
   140          return 0 ether;
   141      }
   142  
   143      function onERC721Received(
   144          address /*operator*/,
   145          address sender /*from*/,
   146          uint256 tokenID /*id*/,
   147          bytes calldata /*data*/
   148      ) external  returns (bytes4) {
   149          require(
   150              T200NFT[tokenID]  || T800NFT[tokenID] || T2000NFT[tokenID],
   151              "Staking: not allowed token"
   152          );
   153  
   154          // A deposit T1  , withdraw T1, A send T1 to B, B deposit T1,  A deposit T2
   155          if (withdrawIDToAddress[tokenID] != address(0)) {
   156              address withdrawAddress = withdrawIDToAddress[tokenID];
   157              delete withdrawAddressToID[withdrawAddress];
   158              delete withdrawIDToAddress[tokenID];
   159          }
   160          
   161  
   162          if (withdrawAddressToID[sender] > 0) {
   163  //            require(
   164  //                token.ownerOf(withdrawAddressToID[sender]) != address(this),
   165  //                "Staking: Have not withdraw"
   166  //            );
   167  
   168              uint256 withdrawTokenID = withdrawAddressToID[sender];
   169              delete withdrawAddressToID[sender];
   170              delete withdrawIDToAddress[withdrawTokenID];
   171          }
   172  
   173          depoistNFT[sender] = tokenID;
   174          return
   175          bytes4(
   176              keccak256(
   177                  "onERC721Received(address,address,uint256,bytes)"
   178              )
   179          );
   180      }
   181  }