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

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity ^0.8.17;
     3  
     4  import "@openzeppelin/contracts/access/Ownable.sol";
     5  import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
     6  import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
     7  import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
     8  import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
     9  import "./IDeposit.sol";
    10  import "hardhat/console.sol";
    11  
    12  contract NFT is ERC1155, Ownable {
    13      constructor() ERC1155("") Ownable() {}
    14  
    15      function mint(address to, uint256 id) external onlyOwner {
    16          //console.log(id);
    17          _mint(to, id, 1, "");
    18      }
    19  }
    20  
    21  contract Staking is IDeposit, IERC1155Receiver, Initializable {
    22      uint256 constant T50 = uint256(keccak256("50AMT"));
    23      uint256 constant T100 = uint256(keccak256("100AMT"));
    24      uint256 constant T500 = uint256(keccak256("500AMT"));
    25  
    26      IERC1155 token;
    27      mapping(address => uint256) depoistNFT;
    28      mapping(address => uint256) depositExpire;
    29  
    30      constructor() {}
    31  
    32      function supportsInterface(
    33          bytes4 interfaceId
    34      ) external pure returns (bool) {
    35          return
    36          interfaceId == type(IDeposit).interfaceId ||
    37          interfaceId == type(IERC1155Receiver).interfaceId;
    38      }
    39  
    40      function initialize(address addr) public initializer {
    41          token = IERC1155(addr);
    42      }
    43  
    44      function deposit(
    45          bytes calldata pubkey,
    46          bytes calldata signature,
    47          uint256 tokenID
    48      ) external {
    49          require(pubkey.length == 48, "Staking: invalid public key");
    50          require(signature.length == 96, "Staking: invalid signature");
    51          require(
    52              tokenID == T50 || tokenID == T100 || tokenID == T500,
    53              "Staking: not allowed token"
    54          );
    55          require(depoistNFT[msg.sender] == 0, "Staking: have deposited");
    56          require(
    57              token.balanceOf(msg.sender, tokenID) > 0,
    58              "Staking: Insuficient Allowance"
    59          );
    60          require(
    61              token.isApprovedForAll(msg.sender, address(this)),
    62              "Staking: caller is not approved"
    63          );
    64  
    65          token.safeTransferFrom(msg.sender, address(this), tokenID, 1, "");
    66  
    67          depoistNFT[msg.sender] = tokenID;
    68          depositExpire[msg.sender] = block.timestamp + 365 days;
    69  
    70          emit DepositEvent(pubkey, nftToAmount(tokenID), signature);
    71      }
    72  
    73      function withdraw() external {
    74          require(depoistNFT[msg.sender] > 0, "Staking: not deposited");
    75          require(
    76              depositExpire[msg.sender] <= block.timestamp,
    77              "Staking: token is locked"
    78          );
    79  
    80          uint256 id = depoistNFT[msg.sender];
    81          delete depoistNFT[msg.sender];
    82          delete depositExpire[msg.sender];
    83  
    84          token.safeTransferFrom(address(this), msg.sender, id, 1, "");
    85          emit WithdrawnEvent(nftToAmount(id));
    86      }
    87  
    88      function depositsOf(address account) external view returns (uint256) {
    89          return depoistNFT[account];
    90      }
    91  
    92      function depositUnlockingTimestamp(
    93          address account
    94      ) external view returns (uint256) {
    95          return depositExpire[account];
    96      }
    97  
    98      function disperseAMT(
    99          address payable[] calldata recipients,
   100          uint256[] calldata amounts
   101      ) external payable {
   102          require(
   103              recipients.length > 0 && recipients.length == amounts.length,
   104              "the lenght of receipts not equal amounts or length is 0 "
   105          );
   106  
   107          uint256 totalAmount;
   108          for (uint i = 0; i < amounts.length; ) {
   109              require(amounts[i] <= 0.7083 ether, "beyond the max rewards");
   110              unchecked {
   111                  totalAmount += amounts[i];
   112                  ++i;
   113              }
   114          }
   115          require(msg.value >= totalAmount, "Insufficient AMT sent");
   116          for (uint i = 0; i < recipients.length; i++) {
   117              recipients[i].transfer(amounts[i]);
   118          }
   119      }
   120  
   121      function nftToAmount(uint256 id) internal pure returns (uint256) {
   122          if (id == T50) {
   123              return 50 ether;
   124          }
   125  
   126          if (id == T100) {
   127              return 100 ether;
   128          }
   129  
   130          if (id == T500) {
   131              return 500 ether;
   132          }
   133  
   134          return 0;
   135      }
   136  
   137      function onERC1155Received(
   138          address /*operator*/,
   139          address /*from*/,
   140          uint256 /*id*/,
   141          uint256 /*value*/,
   142          bytes calldata /*data*/
   143      ) external pure returns (bytes4) {
   144          return
   145          bytes4(
   146              keccak256(
   147                  "onERC1155Received(address,address,uint256,uint256,bytes)"
   148              )
   149          );
   150      }
   151  
   152      function onERC1155BatchReceived(
   153          address /*operator*/,
   154          address /*from*/,
   155          uint256[] calldata /*ids*/,
   156          uint256[] calldata /*values*/,
   157          bytes calldata /*data*/
   158      ) external returns (bytes4) {}
   159  }