github.com/amazechain/amc@v0.1.3/contracts/deposit/AMT/Deposit.sol (about) 1 // SPDX-License-Identifier: MIT 2 pragma solidity ^0.8.0; 3 4 5 import "@openzeppelin/contracts@v4.9.0/access/Ownable.sol"; 6 import "./IDeposit.sol"; 7 8 9 contract Deposit is Ownable, IDeposit { 10 // using Address for address payable; 11 12 mapping(address => uint256) private deposits; 13 mapping(address => uint64) private depositTime; 14 uint64 private depositLockingTime; 15 uint64 private fiftyDepositLimit; 16 uint64 private oneHundredDepositLimit; 17 uint64 private fiveHundredDepositLimit; 18 // 19 uint256 private allDeposits = 0; 20 uint64 private fiftyDepositCount = 0; 21 uint64 private oneHundredDepositCount = 0; 22 uint64 private fiveHundredDepositCount = 0; 23 24 uint256 constant private fiftyDeposit = 50 ether; 25 uint256 constant private oneHundredDeposit = 100 ether; 26 uint256 constant private fiveHundredDeposit = 500 ether; 27 28 29 modifier onlyOperator() { 30 require(msg.sender == owner(), "Caller is not Operator"); 31 _; 32 } 33 34 modifier onlyDeposit() { 35 require(deposits[msg.sender] > 0, "Do not have deposit"); 36 _; 37 } 38 39 constructor (uint64 _depositLockingTime, uint64 _fiftyDepositLimit, uint64 _oneHundredDepositLimit, uint64 _fiveHundredDepositLimit) Ownable() { 40 depositLockingTime = _depositLockingTime; 41 fiftyDepositLimit = _fiftyDepositLimit; 42 oneHundredDepositLimit = _oneHundredDepositLimit; 43 fiveHundredDepositLimit = _fiveHundredDepositLimit; 44 } 45 46 function depositsOf(address payee) public view override returns (uint256) { 47 return deposits[payee]; 48 } 49 50 function depositUnlockingTimestamp(address payee) public view override returns (uint64) { 51 require(depositTime[payee] > 0, "DepositContract: do not have deposit"); 52 return depositTime[payee] + depositLockingTime; 53 } 54 55 function getDepositCount() public view override returns (uint256) { 56 return allDeposits; 57 } 58 59 function depositAllowed(uint256 amount) public view returns (bool) { 60 require(deposits[msg.sender] == 0, "DepositContract: you already deposited"); 61 require(amount == oneHundredDeposit || amount == fiveHundredDeposit || amount == fiftyDeposit, "DepositContract: payee is not allowed to deposit"); 62 // 63 if (amount == fiftyDeposit) { 64 require(fiftyDepositLimit > fiftyDepositCount, "10 AMC Deposit Limit has been reached"); 65 } 66 // 67 if (amount == oneHundredDeposit) { 68 require(oneHundredDepositLimit > oneHundredDepositCount , "100 AMC Deposit Limit has been reached"); 69 } 70 // 71 if (amount == fiveHundredDeposit) { 72 require(fiveHundredDepositLimit > fiveHundredDepositCount, "500 AMC Deposit Limit has been reached"); 73 } 74 return true; 75 } 76 77 function deposit(bytes calldata pubkey, bytes calldata signature) public payable virtual override { 78 79 uint256 amount = msg.value; 80 require(depositAllowed(amount), "DepositContract: payee is not allowed to deposit"); 81 require(pubkey.length == 48, "DepositContract: invalid pubkey length"); 82 require(signature.length == 96, "DepositContract: invalid signature length"); 83 84 // 85 deposits[msg.sender] = amount; 86 depositTime[msg.sender] = uint64(block.timestamp); 87 allDeposits += amount; 88 // 89 if (amount == fiftyDeposit) { 90 fiftyDepositCount++; 91 } 92 // 93 if (amount == oneHundredDeposit) { 94 oneHundredDepositCount++; 95 } 96 // 97 if (amount == fiveHundredDeposit) { 98 fiveHundredDepositCount++; 99 } 100 101 emit DepositEvent(pubkey, amount, signature); 102 } 103 104 function withdrawalAllowed(uint64 timestamp) public view returns (bool) { 105 require(deposits[msg.sender] > 0 && depositTime[msg.sender] > 0, "Do not have deposits"); 106 require(address(this).balance >= deposits[msg.sender], "Insufficient balance"); 107 require(depositTime[msg.sender] + depositLockingTime <= timestamp, "Deposit is locking"); 108 return true; 109 } 110 111 function withdraw() public payable virtual override onlyDeposit { 112 113 require(withdrawalAllowed(uint64(block.timestamp)), "DepositContract: payee is not allowed to deposit"); 114 uint256 amount = deposits[msg.sender]; 115 // 116 sendValue(payable(msg.sender), amount); 117 delete deposits[msg.sender]; 118 delete depositTime[msg.sender]; 119 120 // 121 if (amount == fiftyDeposit) { 122 fiftyDepositCount--; 123 } 124 // 125 if (amount == oneHundredDeposit) { 126 oneHundredDepositCount--; 127 } 128 // 129 if (amount == fiveHundredDeposit) { 130 fiveHundredDepositCount--; 131 } 132 133 allDeposits -= amount; 134 emit WithdrawnEvent(amount); 135 } 136 137 function addDepositLimit(uint256 amount, uint64 limit) public virtual onlyOperator { 138 // 139 if (amount == fiftyDeposit) { 140 fiftyDepositLimit += limit; 141 } 142 // 143 if (amount == oneHundredDeposit) { 144 oneHundredDepositLimit += limit; 145 } 146 // 147 if (amount == fiveHundredDeposit) { 148 fiveHundredDepositLimit += limit; 149 } 150 } 151 function getDepositLimit(uint256 amount) public view returns(uint64) { 152 // 153 if (amount == fiftyDeposit) { 154 return fiftyDepositLimit; 155 } 156 // 157 if (amount == oneHundredDeposit) { 158 return oneHundredDepositLimit; 159 } 160 // 161 if (amount == fiveHundredDeposit) { 162 return fiveHundredDepositLimit; 163 } 164 165 return 0; 166 } 167 168 function getDepositRemain() public view returns(uint64, uint64, uint64) { 169 uint64 fiftyDepositRemain = fiftyDepositLimit - fiftyDepositCount; 170 uint64 oneHundredDepositRemain = oneHundredDepositLimit - oneHundredDepositCount; 171 uint64 fiveHundredDepositRemain = fiveHundredDepositLimit - fiveHundredDepositCount; 172 return (fiftyDepositRemain, oneHundredDepositRemain, fiveHundredDepositRemain); 173 } 174 175 function sendValue(address payable recipient, uint256 amount) private { 176 require(address(this).balance >= amount, "Insufficient balance"); 177 (bool success, ) = recipient.call{value: amount}(""); 178 require(success, "Unable to send value, recipient may have reverted"); 179 } 180 181 } 182 183