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 }