├── GameFiInviteV1.sol ├── timelock.sol ├── GameFiGminerV1.sol ├── GameFiPoolsV1.sol └── GameFiToken.sol /GameFiInviteV1.sol: -------------------------------------------------------------------------------- 1 | // File: contracts/v1-mining/interface/IGameFiInviteV1.sol 2 | 3 | // SPDX-License-Identifier: MIT 4 | 5 | pragma solidity 0.7.4; 6 | 7 | interface IGameFiInviteV1 { 8 | 9 | struct UserInfo { 10 | address upper; 11 | address[] lowers; 12 | uint256 startBlock; 13 | } 14 | 15 | event InviteV1(address indexed owner, address indexed upper, uint256 indexed height); 16 | 17 | function inviteCount() external view returns (uint256); 18 | 19 | function inviteUpper1(address) external view returns (address); 20 | 21 | function inviteLower1(address) external view returns (address[] memory); 22 | 23 | function register() external returns (bool); 24 | 25 | function acceptInvitation(address) external returns (bool); 26 | 27 | 28 | } 29 | 30 | // File: contracts/v1-mining/library/ErrorCode.sol 31 | 32 | 33 | pragma solidity 0.7.4; 34 | 35 | library ErrorCode { 36 | 37 | string constant FORBIDDEN = 'GameFi:FORBIDDEN'; 38 | string constant IDENTICAL_ADDRESSES = 'GameFi:IDENTICAL_ADDRESSES'; 39 | string constant ZERO_ADDRESS = 'GameFi:ZERO_ADDRESS'; 40 | string constant INVALID_ADDRESSES = 'GameFi:INVALID_ADDRESSES'; 41 | string constant BALANCE_INSUFFICIENT = 'GameFi:BALANCE_INSUFFICIENT'; 42 | string constant REWARDTOTAL_LESS_THAN_REWARDPROVIDE = 'GameFi:REWARDTOTAL_LESS_THAN_REWARDPROVIDE'; 43 | string constant PARAMETER_TOO_LONG = 'GameFi:PARAMETER_TOO_LONG'; 44 | string constant REGISTERED = 'GameFi:REGISTERED'; 45 | string constant MINING_NOT_STARTED = 'GameFi:MINING_NOT_STARTED'; 46 | string constant END_OF_MINING = 'GameFi:END_OF_MINING'; 47 | string constant POOL_NOT_EXIST_OR_END_OF_MINING = 'GameFi:POOL_NOT_EXIST_OR_END_OF_MINING'; 48 | 49 | } 50 | 51 | // File: contracts/v1-mining/implement/GameFiInviteV1.sol 52 | 53 | 54 | pragma solidity 0.7.4; 55 | 56 | 57 | 58 | contract GameFiInviteV1 is IGameFiInviteV1 { 59 | 60 | address public constant ZERO = address(0); 61 | uint256 public startBlock; 62 | address[] public inviteUserInfoV1; 63 | mapping(address => UserInfo) public inviteUserInfoV2; 64 | 65 | constructor () { 66 | startBlock = block.number; 67 | } 68 | 69 | function inviteCount() override external view returns (uint256) { 70 | return inviteUserInfoV1.length; 71 | } 72 | 73 | function inviteUpper1(address _owner) override external view returns (address) { 74 | return inviteUserInfoV2[_owner].upper; 75 | } 76 | 77 | 78 | function inviteLower1(address _owner) override external view returns (address[] memory) { 79 | return inviteUserInfoV2[_owner].lowers; 80 | } 81 | 82 | function register() override external returns (bool) { 83 | UserInfo storage user = inviteUserInfoV2[tx.origin]; 84 | require(0 == user.startBlock, ErrorCode.REGISTERED); 85 | user.upper = ZERO; 86 | user.startBlock = block.number; 87 | inviteUserInfoV1.push(tx.origin); 88 | 89 | emit InviteV1(tx.origin, user.upper, user.startBlock); 90 | 91 | return true; 92 | } 93 | 94 | function acceptInvitation(address _inviter) override external returns (bool) { 95 | require(msg.sender != _inviter, ErrorCode.FORBIDDEN); 96 | UserInfo storage user = inviteUserInfoV2[msg.sender]; 97 | require(0 == user.startBlock, ErrorCode.REGISTERED); 98 | UserInfo storage upper = inviteUserInfoV2[_inviter]; 99 | if (0 == upper.startBlock) { 100 | upper.upper = ZERO; 101 | upper.startBlock = block.number; 102 | inviteUserInfoV1.push(_inviter); 103 | 104 | emit InviteV1(_inviter, upper.upper, upper.startBlock); 105 | } 106 | user.upper = _inviter; 107 | upper.lowers.push(msg.sender); 108 | user.startBlock = block.number; 109 | inviteUserInfoV1.push(msg.sender); 110 | 111 | emit InviteV1(msg.sender, user.upper, user.startBlock); 112 | 113 | return true; 114 | } 115 | 116 | 117 | } 118 | -------------------------------------------------------------------------------- /timelock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.6; 3 | 4 | library SafeMath { 5 | /** 6 | * @dev Returns the addition of two unsigned integers, reverting on 7 | * overflow. 8 | * 9 | * Counterpart to Solidity's `+` operator. 10 | * 11 | * Requirements: 12 | * 13 | * - Addition cannot overflow. 14 | */ 15 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 16 | uint256 c = a + b; 17 | require(c >= a, "SafeMath: addition overflow"); 18 | 19 | return c; 20 | } 21 | 22 | /** 23 | * @dev Returns the subtraction of two unsigned integers, reverting on 24 | * overflow (when the result is negative). 25 | * 26 | * Counterpart to Solidity's `-` operator. 27 | * 28 | * Requirements: 29 | * 30 | * - Subtraction cannot overflow. 31 | */ 32 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 33 | return sub(a, b, "SafeMath: subtraction overflow"); 34 | } 35 | 36 | /** 37 | * @dev Returns the subtraction of two unsigned integers, reverting with custom message on 38 | * overflow (when the result is negative). 39 | * 40 | * Counterpart to Solidity's `-` operator. 41 | * 42 | * Requirements: 43 | * 44 | * - Subtraction cannot overflow. 45 | */ 46 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 47 | require(b <= a, errorMessage); 48 | uint256 c = a - b; 49 | 50 | return c; 51 | } 52 | 53 | /** 54 | * @dev Returns the multiplication of two unsigned integers, reverting on 55 | * overflow. 56 | * 57 | * Counterpart to Solidity's `*` operator. 58 | * 59 | * Requirements: 60 | * 61 | * - Multiplication cannot overflow. 62 | */ 63 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 64 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 65 | // benefit is lost if 'b' is also tested. 66 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 67 | if (a == 0) { 68 | return 0; 69 | } 70 | 71 | uint256 c = a * b; 72 | require(c / a == b, "SafeMath: multiplication overflow"); 73 | 74 | return c; 75 | } 76 | 77 | /** 78 | * @dev Returns the integer division of two unsigned integers. Reverts on 79 | * division by zero. The result is rounded towards zero. 80 | * 81 | * Counterpart to Solidity's `/` operator. Note: this function uses a 82 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 83 | * uses an invalid opcode to revert (consuming all remaining gas). 84 | * 85 | * Requirements: 86 | * 87 | * - The divisor cannot be zero. 88 | */ 89 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 90 | return div(a, b, "SafeMath: division by zero"); 91 | } 92 | 93 | /** 94 | * @dev Returns the integer division of two unsigned integers. Reverts with custom message on 95 | * division by zero. The result is rounded towards zero. 96 | * 97 | * Counterpart to Solidity's `/` operator. Note: this function uses a 98 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 99 | * uses an invalid opcode to revert (consuming all remaining gas). 100 | * 101 | * Requirements: 102 | * 103 | * - The divisor cannot be zero. 104 | */ 105 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 106 | require(b > 0, errorMessage); 107 | uint256 c = a / b; 108 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 109 | 110 | return c; 111 | } 112 | 113 | /** 114 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 115 | * Reverts when dividing by zero. 116 | * 117 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 118 | * opcode (which leaves remaining gas untouched) while Solidity uses an 119 | * invalid opcode to revert (consuming all remaining gas). 120 | * 121 | * Requirements: 122 | * 123 | * - The divisor cannot be zero. 124 | */ 125 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 126 | return mod(a, b, "SafeMath: modulo by zero"); 127 | } 128 | 129 | /** 130 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 131 | * Reverts with custom message when dividing by zero. 132 | * 133 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 134 | * opcode (which leaves remaining gas untouched) while Solidity uses an 135 | * invalid opcode to revert (consuming all remaining gas). 136 | * 137 | * Requirements: 138 | * 139 | * - The divisor cannot be zero. 140 | */ 141 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 142 | require(b != 0, errorMessage); 143 | return a % b; 144 | } 145 | } 146 | interface IERC20 { 147 | /** 148 | * @dev Returns the amount of tokens in existence. 149 | */ 150 | function totalSupply() external view returns (uint256); 151 | 152 | /** 153 | * @dev Returns the amount of tokens owned by `account`. 154 | */ 155 | function balanceOf(address account) external view returns (uint256); 156 | 157 | /** 158 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 159 | * 160 | * Returns a boolean value indicating whether the operation succeeded. 161 | * 162 | * Emits a {Transfer} event. 163 | */ 164 | function transfer(address recipient, uint256 amount) external returns (bool); 165 | 166 | /** 167 | * @dev Returns the remaining number of tokens that `spender` will be 168 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 169 | * zero by default. 170 | * 171 | * This value changes when {approve} or {transferFrom} are called. 172 | */ 173 | function allowance(address owner, address spender) external view returns (uint256); 174 | 175 | /** 176 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 177 | * 178 | * Returns a boolean value indicating whether the operation succeeded. 179 | * 180 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 181 | * that someone may use both the old and the new allowance by unfortunate 182 | * transaction ordering. One possible solution to mitigate this race 183 | * condition is to first reduce the spender's allowance to 0 and set the 184 | * desired value afterwards: 185 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 186 | * 187 | * Emits an {Approval} event. 188 | */ 189 | function approve(address spender, uint256 amount) external returns (bool); 190 | 191 | /** 192 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 193 | * allowance mechanism. `amount` is then deducted from the caller's 194 | * allowance. 195 | * 196 | * Returns a boolean value indicating whether the operation succeeded. 197 | * 198 | * Emits a {Transfer} event. 199 | */ 200 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 201 | 202 | /** 203 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 204 | * another (`to`). 205 | * 206 | * Note that `value` may be zero. 207 | */ 208 | event Transfer(address indexed from, address indexed to, uint256 value); 209 | 210 | /** 211 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 212 | * a call to {approve}. `value` is the new allowance. 213 | */ 214 | event Approval(address indexed owner, address indexed spender, uint256 value); 215 | } 216 | library Address { 217 | /** 218 | * @dev Returns true if `account` is a contract. 219 | * 220 | * [IMPORTANT] 221 | * ==== 222 | * It is unsafe to assume that an address for which this function returns 223 | * false is an externally-owned account (EOA) and not a contract. 224 | * 225 | * Among others, `isContract` will return false for the following 226 | * types of addresses: 227 | * 228 | * - an externally-owned account 229 | * - a contract in construction 230 | * - an address where a contract will be created 231 | * - an address where a contract lived, but was destroyed 232 | * ==== 233 | */ 234 | function isContract(address account) internal view returns (bool) { 235 | // This method relies on extcodesize, which returns 0 for contracts in 236 | // construction, since the code is only stored at the end of the 237 | // constructor execution. 238 | 239 | uint256 size; 240 | // solhint-disable-next-line no-inline-assembly 241 | assembly { size := extcodesize(account) } 242 | return size > 0; 243 | } 244 | 245 | /** 246 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 247 | * `recipient`, forwarding all available gas and reverting on errors. 248 | * 249 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 250 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 251 | * imposed by `transfer`, making them unable to receive funds via 252 | * `transfer`. {sendValue} removes this limitation. 253 | * 254 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 255 | * 256 | * IMPORTANT: because control is transferred to `recipient`, care must be 257 | * taken to not create reentrancy vulnerabilities. Consider using 258 | * {ReentrancyGuard} or the 259 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 260 | */ 261 | function sendValue(address payable recipient, uint256 amount) internal { 262 | require(address(this).balance >= amount, "Address: insufficient balance"); 263 | 264 | // solhint-disable-next-line avoid-low-level-calls, avoid-call-value 265 | (bool success, ) = recipient.call{ value: amount }(""); 266 | require(success, "Address: unable to send value, recipient may have reverted"); 267 | } 268 | 269 | /** 270 | * @dev Performs a Solidity function call using a low level `call`. A 271 | * plain`call` is an unsafe replacement for a function call: use this 272 | * function instead. 273 | * 274 | * If `target` reverts with a revert reason, it is bubbled up by this 275 | * function (like regular Solidity function calls). 276 | * 277 | * Returns the raw returned data. To convert to the expected return value, 278 | * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. 279 | * 280 | * Requirements: 281 | * 282 | * - `target` must be a contract. 283 | * - calling `target` with `data` must not revert. 284 | * 285 | * _Available since v3.1._ 286 | */ 287 | function functionCall(address target, bytes memory data) internal returns (bytes memory) { 288 | return functionCall(target, data, "Address: low-level call failed"); 289 | } 290 | 291 | /** 292 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with 293 | * `errorMessage` as a fallback revert reason when `target` reverts. 294 | * 295 | * _Available since v3.1._ 296 | */ 297 | function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { 298 | return functionCallWithValue(target, data, 0, errorMessage); 299 | } 300 | 301 | /** 302 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 303 | * but also transferring `value` wei to `target`. 304 | * 305 | * Requirements: 306 | * 307 | * - the calling contract must have an ETH balance of at least `value`. 308 | * - the called Solidity function must be `payable`. 309 | * 310 | * _Available since v3.1._ 311 | */ 312 | function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { 313 | return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); 314 | } 315 | 316 | /** 317 | * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but 318 | * with `errorMessage` as a fallback revert reason when `target` reverts. 319 | * 320 | * _Available since v3.1._ 321 | */ 322 | function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { 323 | require(address(this).balance >= value, "Address: insufficient balance for call"); 324 | require(isContract(target), "Address: call to non-contract"); 325 | 326 | // solhint-disable-next-line avoid-low-level-calls 327 | (bool success, bytes memory returndata) = target.call{ value: value }(data); 328 | return _verifyCallResult(success, returndata, errorMessage); 329 | } 330 | 331 | /** 332 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 333 | * but performing a static call. 334 | * 335 | * _Available since v3.3._ 336 | */ 337 | function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { 338 | return functionStaticCall(target, data, "Address: low-level static call failed"); 339 | } 340 | 341 | /** 342 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 343 | * but performing a static call. 344 | * 345 | * _Available since v3.3._ 346 | */ 347 | function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { 348 | require(isContract(target), "Address: static call to non-contract"); 349 | 350 | // solhint-disable-next-line avoid-low-level-calls 351 | (bool success, bytes memory returndata) = target.staticcall(data); 352 | return _verifyCallResult(success, returndata, errorMessage); 353 | } 354 | 355 | function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { 356 | if (success) { 357 | return returndata; 358 | } else { 359 | // Look for revert reason and bubble it up if present 360 | if (returndata.length > 0) { 361 | // The easiest way to bubble the revert reason is using memory via assembly 362 | 363 | // solhint-disable-next-line no-inline-assembly 364 | assembly { 365 | let returndata_size := mload(returndata) 366 | revert(add(32, returndata), returndata_size) 367 | } 368 | } else { 369 | revert(errorMessage); 370 | } 371 | } 372 | } 373 | } 374 | library SafeERC20 { 375 | using SafeMath for uint256; 376 | using Address for address; 377 | 378 | function safeTransfer(IERC20 token, address to, uint256 value) internal { 379 | _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 380 | } 381 | 382 | function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { 383 | _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 384 | } 385 | 386 | /** 387 | * @dev Deprecated. This function has issues similar to the ones found in 388 | * {IERC20-approve}, and its usage is discouraged. 389 | * 390 | * Whenever possible, use {safeIncreaseAllowance} and 391 | * {safeDecreaseAllowance} instead. 392 | */ 393 | function safeApprove(IERC20 token, address spender, uint256 value) internal { 394 | // safeApprove should only be called when setting an initial allowance, 395 | // or when resetting it to zero. To increase and decrease it, use 396 | // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' 397 | // solhint-disable-next-line max-line-length 398 | require((value == 0) || (token.allowance(address(this), spender) == 0), 399 | "SafeERC20: approve from non-zero to non-zero allowance" 400 | ); 401 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 402 | } 403 | 404 | function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { 405 | uint256 newAllowance = token.allowance(address(this), spender).add(value); 406 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 407 | } 408 | 409 | function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { 410 | uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); 411 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 412 | } 413 | 414 | /** 415 | * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement 416 | * on the return value: the return value is optional (but if data is returned, it must not be false). 417 | * @param token The token targeted by the call. 418 | * @param data The call data (encoded using abi.encode or one of its variants). 419 | */ 420 | function _callOptionalReturn(IERC20 token, bytes memory data) private { 421 | // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since 422 | // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that 423 | // the target address contains contract code and also asserts for success in the low-level call. 424 | 425 | bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); 426 | if (returndata.length > 0) { // Return data is optional 427 | // solhint-disable-next-line max-line-length 428 | require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); 429 | } 430 | } 431 | } 432 | 433 | contract TimeLock { 434 | using SafeMath for uint; 435 | using SafeERC20 for IERC20; 436 | 437 | IERC20 public token; 438 | uint constant public PERIOD = 1 days; 439 | uint constant public CYCLE_TIMES = 720; 440 | uint public fixedQuantity; 441 | uint public startTime; 442 | uint public constant delay = 180 days; 443 | uint public cycle; 444 | uint public hasReward; // Rewards already withdrawn 445 | address public beneficiary; 446 | // string public introduce; 447 | 448 | event WithDraw(address indexed operator, address indexed to, uint amount); 449 | 450 | constructor( 451 | address _beneficiary, 452 | address _token, 453 | uint _fixedQuantity, 454 | uint _startTime 455 | //uint _delay, 456 | // string memory _introduce 457 | ) public { 458 | require(_beneficiary != address(0) && _token != address(0), "TimeLock: zero address"); 459 | require(_fixedQuantity > 0, "TimeLock: fixedQuantity is zero"); 460 | beneficiary = _beneficiary; 461 | token = IERC20(_token); 462 | fixedQuantity = _fixedQuantity; 463 | //delay = _delay; 464 | if(_startTime == 0){ 465 | _startTime = block.timestamp; 466 | } 467 | startTime = _startTime.add(delay); 468 | // introduce = _introduce; 469 | } 470 | 471 | 472 | function getBalance() public view returns (uint) { 473 | return token.balanceOf(address(this)); 474 | } 475 | 476 | function getReward() public view returns (uint) { 477 | // Has ended or not started 478 | if (cycle >= CYCLE_TIMES || block.timestamp <= startTime) { 479 | return 0; 480 | } 481 | uint pCycle = (block.timestamp.sub(startTime)).div(PERIOD); 482 | if (pCycle >= CYCLE_TIMES) { 483 | return token.balanceOf(address(this)); 484 | } 485 | return pCycle.sub(cycle).mul(fixedQuantity); 486 | } 487 | 488 | function withDraw() external { 489 | uint reward = getReward(); 490 | require(reward > 0, "TimeLock: no reward"); 491 | uint pCycle = (block.timestamp.sub(startTime)).div(PERIOD); 492 | cycle = pCycle >= CYCLE_TIMES ? CYCLE_TIMES : pCycle; 493 | hasReward = hasReward.add(reward); 494 | token.safeTransfer(beneficiary, reward); 495 | emit WithDraw(msg.sender, beneficiary, reward); 496 | } 497 | 498 | // Update beneficiary address by the previous beneficiary. 499 | function setBeneficiary(address _newBeneficiary) public { 500 | require(_newBeneficiary != address (0),"Not zero address"); 501 | require(msg.sender == beneficiary, "Not beneficiary"); 502 | beneficiary = _newBeneficiary; 503 | } 504 | } -------------------------------------------------------------------------------- /GameFiGminerV1.sol: -------------------------------------------------------------------------------- 1 | // File: contracts/v1-mining/interface/ITokenGameFi.sol 2 | 3 | // SPDX-License-Identifier: MIT 4 | 5 | pragma solidity 0.7.4; 6 | 7 | interface ITokenGameFi { 8 | 9 | function mint(address recipient, uint256 amount) external; 10 | 11 | function decimals() external view returns (uint8); 12 | 13 | } 14 | 15 | // File: contracts/v1-mining/interface/IGameFiGminerV1.sol 16 | 17 | 18 | pragma solidity 0.7.4; 19 | 20 | 21 | interface IGameFiGminerV1 { 22 | 23 | 24 | struct UserInfo { 25 | uint256 startBlock; 26 | uint256 amount; 27 | uint256 pledgePower; 28 | uint256 pendingReward; 29 | uint256 pledgeRewardDebt; 30 | } 31 | 32 | struct PoolInfo { 33 | uint256 startBlock; 34 | uint256 rewardTotal; 35 | uint256 rewardProvide; 36 | uint256 amount; 37 | uint256 lastRewardBlock; 38 | uint256 rewardPerBlock; 39 | uint256 totalPower; 40 | uint256 endBlock; 41 | uint256 rewardPerShare; 42 | } 43 | 44 | //////////////////////////////////////////////////////////////////////////////////// 45 | 46 | event UpdatePool(bool action, uint256 pool, uint256 startBlock, uint256 rewardTotal, uint256 rewardPerBlock); 47 | 48 | event EndPool(uint256 pool); 49 | 50 | event Stake(uint256 pool, address indexed from, uint256 amount); 51 | 52 | event UpdatePower(uint256 pool, uint256 totalPower, address indexed owner, uint256 ownerPledgePower); 53 | 54 | event UnStake(uint256 pool, address indexed to, uint256 amount); 55 | 56 | event WithdrawReward(uint256 pool, address indexed to, uint256 amount); 57 | 58 | event Mint(uint256 pool, uint256 amount); 59 | 60 | //////////////////////////////////////////////////////////////////////////////////// 61 | 62 | function transferOwnership(address) external; 63 | 64 | function setGameFi(ITokenGameFi) external; 65 | 66 | function deposit(uint256,address, uint256) external; 67 | 68 | function withdraw(uint256, uint256) external; 69 | 70 | function harvest(uint256) external; 71 | 72 | function updatePledgeUser(uint256, address, uint256) external; 73 | 74 | function poolPledgeAddresss(uint256) external view returns (address[] memory); 75 | 76 | function powerScale(uint256, address) external view returns (uint256); 77 | 78 | function pendingReward(uint256, address) external view returns (uint256); 79 | 80 | function setOperateOwner(address, bool) external; 81 | 82 | //////////////////////////////////////////////////////////////////////////////////// 83 | 84 | function addPool(uint256, uint256, uint256) external returns (bool); 85 | 86 | function setRewardPerBlock(uint256, uint256) external; 87 | 88 | function setRewardTotal(uint256, uint256) external; 89 | 90 | //////////////////////////////////////////////////////////////////////////////////// 91 | 92 | } 93 | 94 | // File: contracts/v1-mining/library/ErrorCode.sol 95 | 96 | 97 | pragma solidity 0.7.4; 98 | 99 | library ErrorCode { 100 | 101 | string constant FORBIDDEN = 'GameFi:FORBIDDEN'; 102 | string constant IDENTICAL_ADDRESSES = 'GameFi:IDENTICAL_ADDRESSES'; 103 | string constant ZERO_ADDRESS = 'GameFi:ZERO_ADDRESS'; 104 | string constant INVALID_ADDRESSES = 'GameFi:INVALID_ADDRESSES'; 105 | string constant BALANCE_INSUFFICIENT = 'GameFi:BALANCE_INSUFFICIENT'; 106 | string constant REWARDTOTAL_LESS_THAN_REWARDPROVIDE = 'GameFi:REWARDTOTAL_LESS_THAN_REWARDPROVIDE'; 107 | string constant PARAMETER_TOO_LONG = 'GameFi:PARAMETER_TOO_LONG'; 108 | string constant REGISTERED = 'GameFi:REGISTERED'; 109 | string constant MINING_NOT_STARTED = 'GameFi:MINING_NOT_STARTED'; 110 | string constant END_OF_MINING = 'GameFi:END_OF_MINING'; 111 | string constant POOL_NOT_EXIST_OR_END_OF_MINING = 'GameFi:POOL_NOT_EXIST_OR_END_OF_MINING'; 112 | 113 | } 114 | 115 | // File: @openzeppelin/contracts/token/ERC20/IERC20.sol 116 | 117 | 118 | pragma solidity >=0.6.0 <0.8.0; 119 | 120 | /** 121 | * @dev Interface of the ERC20 standard as defined in the EIP. 122 | */ 123 | interface IERC20 { 124 | /** 125 | * @dev Returns the amount of tokens in existence. 126 | */ 127 | function totalSupply() external view returns (uint256); 128 | 129 | /** 130 | * @dev Returns the amount of tokens owned by `account`. 131 | */ 132 | function balanceOf(address account) external view returns (uint256); 133 | 134 | /** 135 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 136 | * 137 | * Returns a boolean value indicating whether the operation succeeded. 138 | * 139 | * Emits a {Transfer} event. 140 | */ 141 | function transfer(address recipient, uint256 amount) external returns (bool); 142 | 143 | /** 144 | * @dev Returns the remaining number of tokens that `spender` will be 145 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 146 | * zero by default. 147 | * 148 | * This value changes when {approve} or {transferFrom} are called. 149 | */ 150 | function allowance(address owner, address spender) external view returns (uint256); 151 | 152 | /** 153 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 154 | * 155 | * Returns a boolean value indicating whether the operation succeeded. 156 | * 157 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 158 | * that someone may use both the old and the new allowance by unfortunate 159 | * transaction ordering. One possible solution to mitigate this race 160 | * condition is to first reduce the spender's allowance to 0 and set the 161 | * desired value afterwards: 162 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 163 | * 164 | * Emits an {Approval} event. 165 | */ 166 | function approve(address spender, uint256 amount) external returns (bool); 167 | 168 | /** 169 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 170 | * allowance mechanism. `amount` is then deducted from the caller's 171 | * allowance. 172 | * 173 | * Returns a boolean value indicating whether the operation succeeded. 174 | * 175 | * Emits a {Transfer} event. 176 | */ 177 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 178 | 179 | /** 180 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 181 | * another (`to`). 182 | * 183 | * Note that `value` may be zero. 184 | */ 185 | event Transfer(address indexed from, address indexed to, uint256 value); 186 | 187 | /** 188 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 189 | * a call to {approve}. `value` is the new allowance. 190 | */ 191 | event Approval(address indexed owner, address indexed spender, uint256 value); 192 | } 193 | 194 | // File: @openzeppelin/contracts/math/SafeMath.sol 195 | 196 | 197 | pragma solidity >=0.6.0 <0.8.0; 198 | 199 | /** 200 | * @dev Wrappers over Solidity's arithmetic operations with added overflow 201 | * checks. 202 | * 203 | * Arithmetic operations in Solidity wrap on overflow. This can easily result 204 | * in bugs, because programmers usually assume that an overflow raises an 205 | * error, which is the standard behavior in high level programming languages. 206 | * `SafeMath` restores this intuition by reverting the transaction when an 207 | * operation overflows. 208 | * 209 | * Using this library instead of the unchecked operations eliminates an entire 210 | * class of bugs, so it's recommended to use it always. 211 | */ 212 | library SafeMath { 213 | /** 214 | * @dev Returns the addition of two unsigned integers, with an overflow flag. 215 | * 216 | * _Available since v3.4._ 217 | */ 218 | function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { 219 | uint256 c = a + b; 220 | if (c < a) return (false, 0); 221 | return (true, c); 222 | } 223 | 224 | /** 225 | * @dev Returns the substraction of two unsigned integers, with an overflow flag. 226 | * 227 | * _Available since v3.4._ 228 | */ 229 | function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { 230 | if (b > a) return (false, 0); 231 | return (true, a - b); 232 | } 233 | 234 | /** 235 | * @dev Returns the multiplication of two unsigned integers, with an overflow flag. 236 | * 237 | * _Available since v3.4._ 238 | */ 239 | function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { 240 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 241 | // benefit is lost if 'b' is also tested. 242 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 243 | if (a == 0) return (true, 0); 244 | uint256 c = a * b; 245 | if (c / a != b) return (false, 0); 246 | return (true, c); 247 | } 248 | 249 | /** 250 | * @dev Returns the division of two unsigned integers, with a division by zero flag. 251 | * 252 | * _Available since v3.4._ 253 | */ 254 | function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { 255 | if (b == 0) return (false, 0); 256 | return (true, a / b); 257 | } 258 | 259 | /** 260 | * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. 261 | * 262 | * _Available since v3.4._ 263 | */ 264 | function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { 265 | if (b == 0) return (false, 0); 266 | return (true, a % b); 267 | } 268 | 269 | /** 270 | * @dev Returns the addition of two unsigned integers, reverting on 271 | * overflow. 272 | * 273 | * Counterpart to Solidity's `+` operator. 274 | * 275 | * Requirements: 276 | * 277 | * - Addition cannot overflow. 278 | */ 279 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 280 | uint256 c = a + b; 281 | require(c >= a, "SafeMath: addition overflow"); 282 | return c; 283 | } 284 | 285 | /** 286 | * @dev Returns the subtraction of two unsigned integers, reverting on 287 | * overflow (when the result is negative). 288 | * 289 | * Counterpart to Solidity's `-` operator. 290 | * 291 | * Requirements: 292 | * 293 | * - Subtraction cannot overflow. 294 | */ 295 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 296 | require(b <= a, "SafeMath: subtraction overflow"); 297 | return a - b; 298 | } 299 | 300 | /** 301 | * @dev Returns the multiplication of two unsigned integers, reverting on 302 | * overflow. 303 | * 304 | * Counterpart to Solidity's `*` operator. 305 | * 306 | * Requirements: 307 | * 308 | * - Multiplication cannot overflow. 309 | */ 310 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 311 | if (a == 0) return 0; 312 | uint256 c = a * b; 313 | require(c / a == b, "SafeMath: multiplication overflow"); 314 | return c; 315 | } 316 | 317 | /** 318 | * @dev Returns the integer division of two unsigned integers, reverting on 319 | * division by zero. The result is rounded towards zero. 320 | * 321 | * Counterpart to Solidity's `/` operator. Note: this function uses a 322 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 323 | * uses an invalid opcode to revert (consuming all remaining gas). 324 | * 325 | * Requirements: 326 | * 327 | * - The divisor cannot be zero. 328 | */ 329 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 330 | require(b > 0, "SafeMath: division by zero"); 331 | return a / b; 332 | } 333 | 334 | /** 335 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 336 | * reverting when dividing by zero. 337 | * 338 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 339 | * opcode (which leaves remaining gas untouched) while Solidity uses an 340 | * invalid opcode to revert (consuming all remaining gas). 341 | * 342 | * Requirements: 343 | * 344 | * - The divisor cannot be zero. 345 | */ 346 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 347 | require(b > 0, "SafeMath: modulo by zero"); 348 | return a % b; 349 | } 350 | 351 | /** 352 | * @dev Returns the subtraction of two unsigned integers, reverting with custom message on 353 | * overflow (when the result is negative). 354 | * 355 | * CAUTION: This function is deprecated because it requires allocating memory for the error 356 | * message unnecessarily. For custom revert reasons use {trySub}. 357 | * 358 | * Counterpart to Solidity's `-` operator. 359 | * 360 | * Requirements: 361 | * 362 | * - Subtraction cannot overflow. 363 | */ 364 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 365 | require(b <= a, errorMessage); 366 | return a - b; 367 | } 368 | 369 | /** 370 | * @dev Returns the integer division of two unsigned integers, reverting with custom message on 371 | * division by zero. The result is rounded towards zero. 372 | * 373 | * CAUTION: This function is deprecated because it requires allocating memory for the error 374 | * message unnecessarily. For custom revert reasons use {tryDiv}. 375 | * 376 | * Counterpart to Solidity's `/` operator. Note: this function uses a 377 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 378 | * uses an invalid opcode to revert (consuming all remaining gas). 379 | * 380 | * Requirements: 381 | * 382 | * - The divisor cannot be zero. 383 | */ 384 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 385 | require(b > 0, errorMessage); 386 | return a / b; 387 | } 388 | 389 | /** 390 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 391 | * reverting with custom message when dividing by zero. 392 | * 393 | * CAUTION: This function is deprecated because it requires allocating memory for the error 394 | * message unnecessarily. For custom revert reasons use {tryMod}. 395 | * 396 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 397 | * opcode (which leaves remaining gas untouched) while Solidity uses an 398 | * invalid opcode to revert (consuming all remaining gas). 399 | * 400 | * Requirements: 401 | * 402 | * - The divisor cannot be zero. 403 | */ 404 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 405 | require(b > 0, errorMessage); 406 | return a % b; 407 | } 408 | } 409 | 410 | // File: @openzeppelin/contracts/utils/Address.sol 411 | 412 | 413 | pragma solidity >=0.6.2 <0.8.0; 414 | 415 | /** 416 | * @dev Collection of functions related to the address type 417 | */ 418 | library Address { 419 | /** 420 | * @dev Returns true if `account` is a contract. 421 | * 422 | * [IMPORTANT] 423 | * ==== 424 | * It is unsafe to assume that an address for which this function returns 425 | * false is an externally-owned account (EOA) and not a contract. 426 | * 427 | * Among others, `isContract` will return false for the following 428 | * types of addresses: 429 | * 430 | * - an externally-owned account 431 | * - a contract in construction 432 | * - an address where a contract will be created 433 | * - an address where a contract lived, but was destroyed 434 | * ==== 435 | */ 436 | function isContract(address account) internal view returns (bool) { 437 | // This method relies on extcodesize, which returns 0 for contracts in 438 | // construction, since the code is only stored at the end of the 439 | // constructor execution. 440 | 441 | uint256 size; 442 | // solhint-disable-next-line no-inline-assembly 443 | assembly { size := extcodesize(account) } 444 | return size > 0; 445 | } 446 | 447 | /** 448 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 449 | * `recipient`, forwarding all available gas and reverting on errors. 450 | * 451 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 452 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 453 | * imposed by `transfer`, making them unable to receive funds via 454 | * `transfer`. {sendValue} removes this limitation. 455 | * 456 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 457 | * 458 | * IMPORTANT: because control is transferred to `recipient`, care must be 459 | * taken to not create reentrancy vulnerabilities. Consider using 460 | * {ReentrancyGuard} or the 461 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 462 | */ 463 | function sendValue(address payable recipient, uint256 amount) internal { 464 | require(address(this).balance >= amount, "Address: insufficient balance"); 465 | 466 | // solhint-disable-next-line avoid-low-level-calls, avoid-call-value 467 | (bool success, ) = recipient.call{ value: amount }(""); 468 | require(success, "Address: unable to send value, recipient may have reverted"); 469 | } 470 | 471 | /** 472 | * @dev Performs a Solidity function call using a low level `call`. A 473 | * plain`call` is an unsafe replacement for a function call: use this 474 | * function instead. 475 | * 476 | * If `target` reverts with a revert reason, it is bubbled up by this 477 | * function (like regular Solidity function calls). 478 | * 479 | * Returns the raw returned data. To convert to the expected return value, 480 | * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. 481 | * 482 | * Requirements: 483 | * 484 | * - `target` must be a contract. 485 | * - calling `target` with `data` must not revert. 486 | * 487 | * _Available since v3.1._ 488 | */ 489 | function functionCall(address target, bytes memory data) internal returns (bytes memory) { 490 | return functionCall(target, data, "Address: low-level call failed"); 491 | } 492 | 493 | /** 494 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with 495 | * `errorMessage` as a fallback revert reason when `target` reverts. 496 | * 497 | * _Available since v3.1._ 498 | */ 499 | function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { 500 | return functionCallWithValue(target, data, 0, errorMessage); 501 | } 502 | 503 | /** 504 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 505 | * but also transferring `value` wei to `target`. 506 | * 507 | * Requirements: 508 | * 509 | * - the calling contract must have an ETH balance of at least `value`. 510 | * - the called Solidity function must be `payable`. 511 | * 512 | * _Available since v3.1._ 513 | */ 514 | function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { 515 | return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); 516 | } 517 | 518 | /** 519 | * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but 520 | * with `errorMessage` as a fallback revert reason when `target` reverts. 521 | * 522 | * _Available since v3.1._ 523 | */ 524 | function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { 525 | require(address(this).balance >= value, "Address: insufficient balance for call"); 526 | require(isContract(target), "Address: call to non-contract"); 527 | 528 | // solhint-disable-next-line avoid-low-level-calls 529 | (bool success, bytes memory returndata) = target.call{ value: value }(data); 530 | return _verifyCallResult(success, returndata, errorMessage); 531 | } 532 | 533 | /** 534 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 535 | * but performing a static call. 536 | * 537 | * _Available since v3.3._ 538 | */ 539 | function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { 540 | return functionStaticCall(target, data, "Address: low-level static call failed"); 541 | } 542 | 543 | /** 544 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 545 | * but performing a static call. 546 | * 547 | * _Available since v3.3._ 548 | */ 549 | function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { 550 | require(isContract(target), "Address: static call to non-contract"); 551 | 552 | // solhint-disable-next-line avoid-low-level-calls 553 | (bool success, bytes memory returndata) = target.staticcall(data); 554 | return _verifyCallResult(success, returndata, errorMessage); 555 | } 556 | 557 | /** 558 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 559 | * but performing a delegate call. 560 | * 561 | * _Available since v3.4._ 562 | */ 563 | function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { 564 | return functionDelegateCall(target, data, "Address: low-level delegate call failed"); 565 | } 566 | 567 | /** 568 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 569 | * but performing a delegate call. 570 | * 571 | * _Available since v3.4._ 572 | */ 573 | function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { 574 | require(isContract(target), "Address: delegate call to non-contract"); 575 | 576 | // solhint-disable-next-line avoid-low-level-calls 577 | (bool success, bytes memory returndata) = target.delegatecall(data); 578 | return _verifyCallResult(success, returndata, errorMessage); 579 | } 580 | 581 | function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { 582 | if (success) { 583 | return returndata; 584 | } else { 585 | // Look for revert reason and bubble it up if present 586 | if (returndata.length > 0) { 587 | // The easiest way to bubble the revert reason is using memory via assembly 588 | 589 | // solhint-disable-next-line no-inline-assembly 590 | assembly { 591 | let returndata_size := mload(returndata) 592 | revert(add(32, returndata), returndata_size) 593 | } 594 | } else { 595 | revert(errorMessage); 596 | } 597 | } 598 | } 599 | } 600 | 601 | // File: @openzeppelin/contracts/token/ERC20/SafeERC20.sol 602 | 603 | 604 | pragma solidity >=0.6.0 <0.8.0; 605 | 606 | 607 | 608 | 609 | /** 610 | * @title SafeERC20 611 | * @dev Wrappers around ERC20 operations that throw on failure (when the token 612 | * contract returns false). Tokens that return no value (and instead revert or 613 | * throw on failure) are also supported, non-reverting calls are assumed to be 614 | * successful. 615 | * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, 616 | * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. 617 | */ 618 | library SafeERC20 { 619 | using SafeMath for uint256; 620 | using Address for address; 621 | 622 | function safeTransfer(IERC20 token, address to, uint256 value) internal { 623 | _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 624 | } 625 | 626 | function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { 627 | _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 628 | } 629 | 630 | /** 631 | * @dev Deprecated. This function has issues similar to the ones found in 632 | * {IERC20-approve}, and its usage is discouraged. 633 | * 634 | * Whenever possible, use {safeIncreaseAllowance} and 635 | * {safeDecreaseAllowance} instead. 636 | */ 637 | function safeApprove(IERC20 token, address spender, uint256 value) internal { 638 | // safeApprove should only be called when setting an initial allowance, 639 | // or when resetting it to zero. To increase and decrease it, use 640 | // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' 641 | // solhint-disable-next-line max-line-length 642 | require((value == 0) || (token.allowance(address(this), spender) == 0), 643 | "SafeERC20: approve from non-zero to non-zero allowance" 644 | ); 645 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 646 | } 647 | 648 | function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { 649 | uint256 newAllowance = token.allowance(address(this), spender).add(value); 650 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 651 | } 652 | 653 | function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { 654 | uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); 655 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 656 | } 657 | 658 | /** 659 | * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement 660 | * on the return value: the return value is optional (but if data is returned, it must not be false). 661 | * @param token The token targeted by the call. 662 | * @param data The call data (encoded using abi.encode or one of its variants). 663 | */ 664 | function _callOptionalReturn(IERC20 token, bytes memory data) private { 665 | // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since 666 | // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that 667 | // the target address contains contract code and also asserts for success in the low-level call. 668 | 669 | bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); 670 | if (returndata.length > 0) { // Return data is optional 671 | // solhint-disable-next-line max-line-length 672 | require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); 673 | } 674 | } 675 | } 676 | 677 | // File: contracts/v1-mining/implement/GameFiGminerV1.sol 678 | 679 | 680 | pragma solidity 0.7.4; 681 | 682 | 683 | 684 | 685 | 686 | contract GameFiGminerV1 is IGameFiGminerV1 { 687 | 688 | using SafeMath for uint256; 689 | 690 | uint256 public deployBlock; 691 | address public owner; 692 | mapping(address => bool) public operateOwner; 693 | ITokenGameFi public gameFi;//gameFi contract 694 | 695 | uint256 public poolCount = 0; 696 | mapping(uint256 => PoolInfo) public poolInfos; 697 | mapping(uint256 => address[]) public pledgeAddresss; 698 | mapping(uint256 => mapping(address => UserInfo)) public pledgeUserInfo; 699 | 700 | //uint256 public constant invite1Reward = 15;//Level 1 invite rewards,15% 701 | uint256 public rewardTotal = 0;//Total mining bonus 702 | 703 | constructor (ITokenGameFi _gameFi) { 704 | deployBlock = block.number; 705 | owner = msg.sender; 706 | _setOperateOwner(owner, true); 707 | _setGameFi(_gameFi); 708 | } 709 | 710 | //////////////////////////////////////////////////////////////////////////////////// 711 | 712 | function transferOwnership(address _owner) override external { 713 | require(owner == msg.sender, ErrorCode.FORBIDDEN); 714 | require((address(0) != _owner) && (owner != _owner), ErrorCode.INVALID_ADDRESSES); 715 | _setOperateOwner(owner, false); 716 | _setOperateOwner(_owner, true); 717 | owner = _owner; 718 | } 719 | 720 | function setGameFi(ITokenGameFi _gameFi) override external { 721 | _setGameFi(_gameFi); 722 | } 723 | 724 | function _setGameFi(ITokenGameFi _gameFi) internal { 725 | require(owner == msg.sender, ErrorCode.FORBIDDEN); 726 | gameFi = _gameFi; 727 | } 728 | 729 | 730 | function deposit(uint256 _pool, address _user, uint256 _amount) override external { 731 | require(operateOwner[msg.sender], ErrorCode.FORBIDDEN);//only operateOwner 732 | require(0 < _amount, ErrorCode.FORBIDDEN); 733 | PoolInfo storage poolInfo = poolInfos[_pool]; 734 | require(poolInfo.startBlock <= block.number, ErrorCode.MINING_NOT_STARTED); 735 | //require(0 == poolInfo.endBlock, ErrorCode.END_OF_MINING); 736 | 737 | computeReward(_pool); 738 | 739 | provideReward(_pool, poolInfo.rewardPerShare, _user); 740 | 741 | addPower(_pool, _user, _amount); 742 | 743 | setRewardDebt(_pool, poolInfo.rewardPerShare, _user); 744 | 745 | emit Stake(_pool, _user, _amount); 746 | } 747 | 748 | function harvest(uint256 _pool) override external { 749 | 750 | PoolInfo storage poolInfo = poolInfos[_pool]; 751 | require(poolInfo.startBlock <= block.number, ErrorCode.MINING_NOT_STARTED); 752 | 753 | computeReward(_pool); 754 | 755 | provideReward(_pool, poolInfo.rewardPerShare, msg.sender); 756 | 757 | setRewardDebt(_pool, poolInfo.rewardPerShare, msg.sender); 758 | 759 | 760 | } 761 | 762 | function withdraw(uint256 _pool, uint256 _amount) override external { 763 | PoolInfo storage poolInfo = poolInfos[_pool]; 764 | require(poolInfo.startBlock <= block.number, ErrorCode.MINING_NOT_STARTED); 765 | if (0 < _amount) { 766 | UserInfo storage userInfo = pledgeUserInfo[_pool][msg.sender]; 767 | require(_amount <= userInfo.amount, ErrorCode.BALANCE_INSUFFICIENT); 768 | } 769 | 770 | computeReward(_pool); 771 | 772 | provideReward(_pool, poolInfo.rewardPerShare, msg.sender); 773 | 774 | if (0 < _amount) { 775 | subPower(_pool, msg.sender, _amount); 776 | } 777 | 778 | setRewardDebt(_pool, poolInfo.rewardPerShare, msg.sender); 779 | 780 | if (0 < _amount) { 781 | emit UnStake(_pool, msg.sender, _amount); 782 | } 783 | } 784 | 785 | function updatePledgeUser(uint256 _pool, address _user, uint256 _amount) override external { 786 | require(operateOwner[msg.sender], ErrorCode.FORBIDDEN);//only operateOwner 787 | PoolInfo storage poolInfo = poolInfos[_pool]; 788 | require(poolInfo.startBlock <= block.number, ErrorCode.MINING_NOT_STARTED); 789 | 790 | computeReward(_pool); 791 | 792 | provideReward(_pool, poolInfo.rewardPerShare, _user); 793 | 794 | updatePower(_pool, _user, _amount); 795 | 796 | setRewardDebt(_pool, poolInfo.rewardPerShare, _user); 797 | 798 | } 799 | 800 | function poolPledgeAddresss(uint256 _pool) override external view returns (address[] memory) { 801 | return pledgeAddresss[_pool]; 802 | } 803 | 804 | function computeReward(uint256 _pool) internal { 805 | PoolInfo storage poolInfo = poolInfos[_pool]; 806 | if ((0 < poolInfo.totalPower) && (poolInfo.rewardProvide < poolInfo.rewardTotal)) { 807 | uint256 reward = (block.number - poolInfo.lastRewardBlock).mul(poolInfo.rewardPerBlock); 808 | if (poolInfo.rewardProvide.add(reward) > poolInfo.rewardTotal) { 809 | reward = poolInfo.rewardTotal.sub(poolInfo.rewardProvide); 810 | poolInfo.endBlock = block.number; 811 | } 812 | 813 | rewardTotal = rewardTotal.add(reward); 814 | poolInfo.rewardProvide = poolInfo.rewardProvide.add(reward); 815 | poolInfo.rewardPerShare = poolInfo.rewardPerShare.add(reward.mul(1e24).div(poolInfo.totalPower)); 816 | poolInfo.lastRewardBlock = block.number; 817 | 818 | emit Mint(_pool,reward); 819 | 820 | if (0 < poolInfo.endBlock) { 821 | emit EndPool(_pool); 822 | } 823 | } 824 | } 825 | 826 | function addPower(uint256 _pool, address _user, uint256 _amount) internal { 827 | PoolInfo storage poolInfo = poolInfos[_pool]; 828 | poolInfo.amount = poolInfo.amount.add(_amount); 829 | 830 | uint256 pledgePower = _amount; 831 | UserInfo storage userInfo = pledgeUserInfo[_pool][_user]; 832 | userInfo.amount = userInfo.amount.add(_amount); 833 | userInfo.pledgePower = userInfo.pledgePower.add(pledgePower); 834 | poolInfo.totalPower = poolInfo.totalPower.add(pledgePower); 835 | if (0 == userInfo.startBlock) { 836 | userInfo.startBlock = block.number; 837 | pledgeAddresss[_pool].push(msg.sender); 838 | } 839 | 840 | emit UpdatePower(_pool, poolInfo.totalPower, _user, userInfo.pledgePower); 841 | } 842 | 843 | function subPower(uint256 _pool, address _user, uint256 _amount) internal { 844 | PoolInfo storage poolInfo = poolInfos[_pool]; 845 | UserInfo storage userInfo = pledgeUserInfo[_pool][_user]; 846 | if (poolInfo.amount < _amount) { 847 | poolInfo.amount = 0; 848 | }else { 849 | poolInfo.amount = poolInfo.amount.sub(_amount); 850 | } 851 | 852 | uint256 pledgePower = _amount; 853 | userInfo.amount = userInfo.amount.sub(_amount); 854 | if (userInfo.pledgePower < pledgePower) { 855 | userInfo.pledgePower = 0; 856 | }else { 857 | userInfo.pledgePower = userInfo.pledgePower.sub(pledgePower); 858 | } 859 | if (poolInfo.totalPower < pledgePower) { 860 | poolInfo.totalPower = 0; 861 | }else { 862 | poolInfo.totalPower = poolInfo.totalPower.sub(pledgePower); 863 | } 864 | 865 | 866 | emit UpdatePower(_pool, poolInfo.totalPower, _user, userInfo.pledgePower); 867 | } 868 | 869 | function updatePower(uint256 _pool, address _user, uint256 _amount) internal { 870 | UserInfo storage userInfo = pledgeUserInfo[_pool][_user]; 871 | if(_amount > userInfo.amount){ 872 | addPower( _pool, _user, _amount.sub(userInfo.amount)); 873 | }else if(_amount < userInfo.amount){ 874 | subPower( _pool, _user, userInfo.amount.sub(_amount)); 875 | } 876 | } 877 | 878 | function provideReward(uint256 _pool, uint256 _rewardPerShare, address _user) internal { 879 | uint256 pledgeReward = 0; 880 | UserInfo storage userInfo = pledgeUserInfo[_pool][_user]; 881 | if (0 < userInfo.pledgePower) { 882 | pledgeReward = userInfo.pledgePower.mul(_rewardPerShare).sub(userInfo.pledgeRewardDebt).div(1e24); 883 | userInfo.pendingReward = userInfo.pendingReward.add(pledgeReward); 884 | } 885 | 886 | if (0 < userInfo.pendingReward) { 887 | gameFi.mint(_user, userInfo.pendingReward); 888 | emit WithdrawReward(_pool, _user, userInfo.pendingReward); 889 | userInfo.pendingReward = 0; 890 | } 891 | 892 | } 893 | 894 | function setRewardDebt(uint256 _pool, uint256 _rewardPerShare, address _user) internal { 895 | UserInfo storage userInfo = pledgeUserInfo[_pool][_user]; 896 | userInfo.pledgeRewardDebt = userInfo.pledgePower.mul(_rewardPerShare); 897 | } 898 | 899 | function powerScale(uint256 _pool, address _user) override external view returns (uint256) { 900 | PoolInfo memory poolInfo = poolInfos[_pool]; 901 | if (0 == poolInfo.totalPower) { 902 | return 0; 903 | } 904 | 905 | UserInfo memory userInfo = pledgeUserInfo[_pool][_user]; 906 | return (userInfo.pledgePower.mul(100)).div(poolInfo.totalPower); 907 | } 908 | 909 | function pendingReward(uint256 _pool, address _user) override external view returns (uint256) { 910 | uint256 totalReward = 0; 911 | PoolInfo memory poolInfo = poolInfos[_pool]; 912 | if (poolInfo.startBlock <= block.number) { 913 | uint256 rewardPerShare = 0; 914 | if (0 < poolInfo.totalPower) { 915 | uint256 reward = (block.number - poolInfo.lastRewardBlock).mul(poolInfo.rewardPerBlock); 916 | if (poolInfo.rewardProvide.add(reward) > poolInfo.rewardTotal) { 917 | reward = poolInfo.rewardTotal.sub(poolInfo.rewardProvide); 918 | } 919 | rewardPerShare = reward.mul(1e24).div(poolInfo.totalPower); 920 | } 921 | rewardPerShare = rewardPerShare.add(poolInfo.rewardPerShare); 922 | 923 | UserInfo memory userInfo = pledgeUserInfo[_pool][_user]; 924 | totalReward = userInfo.pendingReward; 925 | totalReward = totalReward.add(userInfo.pledgePower.mul(rewardPerShare).sub(userInfo.pledgeRewardDebt).div(1e24)); 926 | } 927 | 928 | return totalReward; 929 | } 930 | 931 | 932 | function setOperateOwner(address _address, bool _bool) override external { 933 | _setOperateOwner(_address, _bool); 934 | } 935 | 936 | function _setOperateOwner(address _address, bool _bool) internal { 937 | require(owner == msg.sender, ErrorCode.FORBIDDEN); 938 | operateOwner[_address] = _bool; 939 | } 940 | 941 | //////////////////////////////////////////////////////////////////////////////////// 942 | 943 | function addPool(uint256 _startBlock, uint256 _rewardTotal, uint256 _rewardPerBlock) override external returns (bool) { 944 | require(operateOwner[msg.sender], ErrorCode.FORBIDDEN); 945 | _startBlock = _startBlock < block.number ? block.number : _startBlock; 946 | uint256 _pool = poolCount; 947 | poolCount = poolCount.add(1); 948 | 949 | PoolInfo storage poolInfo = poolInfos[_pool]; 950 | poolInfo.startBlock = _startBlock; 951 | poolInfo.rewardTotal = _rewardTotal; 952 | poolInfo.rewardProvide = 0; 953 | poolInfo.amount = 0; 954 | poolInfo.lastRewardBlock = _startBlock.sub(1); 955 | poolInfo.rewardPerBlock = _rewardPerBlock; 956 | poolInfo.totalPower = 0; 957 | poolInfo.endBlock = 0; 958 | poolInfo.rewardPerShare = 0; 959 | 960 | emit UpdatePool(true, _pool, poolInfo.startBlock, poolInfo.rewardTotal, poolInfo.rewardPerBlock); 961 | 962 | return true; 963 | } 964 | 965 | function setRewardPerBlock(uint256 _pool, uint256 _rewardPerBlock) override external { 966 | require(operateOwner[msg.sender], ErrorCode.FORBIDDEN); 967 | PoolInfo storage poolInfo = poolInfos[_pool]; 968 | require(0 == poolInfo.endBlock, ErrorCode.POOL_NOT_EXIST_OR_END_OF_MINING); 969 | 970 | computeReward(_pool); 971 | 972 | poolInfo.rewardPerBlock = _rewardPerBlock; 973 | 974 | emit UpdatePool(false, _pool, poolInfo.startBlock, poolInfo.rewardTotal, poolInfo.rewardPerBlock); 975 | } 976 | 977 | function setRewardTotal(uint256 _pool, uint256 _rewardTotal) override external { 978 | require(operateOwner[msg.sender], ErrorCode.FORBIDDEN); 979 | PoolInfo storage poolInfo = poolInfos[_pool]; 980 | require(0 == poolInfo.endBlock, ErrorCode.POOL_NOT_EXIST_OR_END_OF_MINING); 981 | 982 | computeReward(_pool); 983 | 984 | require(poolInfo.rewardProvide < _rewardTotal, ErrorCode.REWARDTOTAL_LESS_THAN_REWARDPROVIDE); 985 | 986 | poolInfo.rewardTotal = _rewardTotal; 987 | 988 | emit UpdatePool(false, _pool, poolInfo.startBlock, poolInfo.rewardTotal, poolInfo.rewardPerBlock); 989 | } 990 | 991 | 992 | } 993 | -------------------------------------------------------------------------------- /GameFiPoolsV1.sol: -------------------------------------------------------------------------------- 1 | // File: contracts/v1-mining/interface/ITokenGameFi.sol 2 | 3 | // SPDX-License-Identifier: MIT 4 | 5 | pragma solidity 0.7.4; 6 | 7 | interface ITokenGameFi { 8 | 9 | function mint(address recipient, uint256 amount) external; 10 | 11 | function decimals() external view returns (uint8); 12 | 13 | } 14 | 15 | // File: contracts/v1-mining/interface/IGameFiInviteV1.sol 16 | 17 | 18 | pragma solidity 0.7.4; 19 | 20 | interface IGameFiInviteV1 { 21 | 22 | struct UserInfo { 23 | address upper; 24 | address[] lowers; 25 | uint256 startBlock; 26 | } 27 | 28 | event InviteV1(address indexed owner, address indexed upper, uint256 indexed height); 29 | 30 | function inviteCount() external view returns (uint256); 31 | 32 | function inviteUpper1(address) external view returns (address); 33 | 34 | function inviteLower1(address) external view returns (address[] memory); 35 | 36 | function register() external returns (bool); 37 | 38 | function acceptInvitation(address) external returns (bool); 39 | 40 | 41 | } 42 | 43 | // File: contracts/v1-mining/library/ErrorCode.sol 44 | 45 | 46 | pragma solidity 0.7.4; 47 | 48 | library ErrorCode { 49 | 50 | string constant FORBIDDEN = 'GameFi:FORBIDDEN'; 51 | string constant IDENTICAL_ADDRESSES = 'GameFi:IDENTICAL_ADDRESSES'; 52 | string constant ZERO_ADDRESS = 'GameFi:ZERO_ADDRESS'; 53 | string constant INVALID_ADDRESSES = 'GameFi:INVALID_ADDRESSES'; 54 | string constant BALANCE_INSUFFICIENT = 'GameFi:BALANCE_INSUFFICIENT'; 55 | string constant REWARDTOTAL_LESS_THAN_REWARDPROVIDE = 'GameFi:REWARDTOTAL_LESS_THAN_REWARDPROVIDE'; 56 | string constant PARAMETER_TOO_LONG = 'GameFi:PARAMETER_TOO_LONG'; 57 | string constant REGISTERED = 'GameFi:REGISTERED'; 58 | string constant MINING_NOT_STARTED = 'GameFi:MINING_NOT_STARTED'; 59 | string constant END_OF_MINING = 'GameFi:END_OF_MINING'; 60 | string constant POOL_NOT_EXIST_OR_END_OF_MINING = 'GameFi:POOL_NOT_EXIST_OR_END_OF_MINING'; 61 | 62 | } 63 | 64 | // File: contracts/v1-mining/implement/GameFiInviteV1.sol 65 | 66 | 67 | pragma solidity 0.7.4; 68 | 69 | 70 | 71 | contract GameFiInviteV1 is IGameFiInviteV1 { 72 | 73 | address public constant ZERO = address(0); 74 | uint256 public startBlock; 75 | address[] public inviteUserInfoV1; 76 | mapping(address => UserInfo) public inviteUserInfoV2; 77 | 78 | constructor () { 79 | startBlock = block.number; 80 | } 81 | 82 | function inviteCount() override external view returns (uint256) { 83 | return inviteUserInfoV1.length; 84 | } 85 | 86 | function inviteUpper1(address _owner) override external view returns (address) { 87 | return inviteUserInfoV2[_owner].upper; 88 | } 89 | 90 | 91 | function inviteLower1(address _owner) override external view returns (address[] memory) { 92 | return inviteUserInfoV2[_owner].lowers; 93 | } 94 | 95 | function register() override external returns (bool) { 96 | UserInfo storage user = inviteUserInfoV2[tx.origin]; 97 | require(0 == user.startBlock, ErrorCode.REGISTERED); 98 | user.upper = ZERO; 99 | user.startBlock = block.number; 100 | inviteUserInfoV1.push(tx.origin); 101 | 102 | emit InviteV1(tx.origin, user.upper, user.startBlock); 103 | 104 | return true; 105 | } 106 | 107 | function acceptInvitation(address _inviter) override external returns (bool) { 108 | require(msg.sender != _inviter, ErrorCode.FORBIDDEN); 109 | UserInfo storage user = inviteUserInfoV2[msg.sender]; 110 | require(0 == user.startBlock, ErrorCode.REGISTERED); 111 | UserInfo storage upper = inviteUserInfoV2[_inviter]; 112 | if (0 == upper.startBlock) { 113 | upper.upper = ZERO; 114 | upper.startBlock = block.number; 115 | inviteUserInfoV1.push(_inviter); 116 | 117 | emit InviteV1(_inviter, upper.upper, upper.startBlock); 118 | } 119 | user.upper = _inviter; 120 | upper.lowers.push(msg.sender); 121 | user.startBlock = block.number; 122 | inviteUserInfoV1.push(msg.sender); 123 | 124 | emit InviteV1(msg.sender, user.upper, user.startBlock); 125 | 126 | return true; 127 | } 128 | 129 | 130 | } 131 | 132 | // File: contracts/v1-mining/interface/IGameFiPoolsV1.sol 133 | 134 | 135 | pragma solidity 0.7.4; 136 | 137 | 138 | 139 | interface IGameFiPoolsV1 { 140 | 141 | struct RewardInfo { 142 | uint256 receiveReward;//receiveReward 143 | uint256 inviteReward;//inviteReward 144 | uint256 pledgeReward;//pledgeReward 145 | } 146 | 147 | struct UserInfo { 148 | uint256 startBlock; 149 | uint256 amount; 150 | uint256 invitePower; 151 | uint256 pledgePower; 152 | uint256 pendingReward; 153 | uint256 inviteRewardDebt; 154 | uint256 pledgeRewardDebt; 155 | } 156 | 157 | 158 | struct PoolViewInfo { 159 | address lp; 160 | string name; 161 | uint256 multiple; 162 | uint256 priority; 163 | } 164 | 165 | struct PoolInfo { 166 | uint256 startBlock; 167 | uint256 rewardTotal; 168 | uint256 rewardProvide; 169 | address lp; 170 | uint256 amount; 171 | uint256 lastRewardBlock; 172 | uint256 rewardPerBlock; 173 | uint256 totalPower; 174 | uint256 endBlock; 175 | uint256 rewardPerShare; 176 | uint256 invite1Reward; 177 | } 178 | 179 | //////////////////////////////////////////////////////////////////////////////////// 180 | 181 | event InviteRegister(address indexed self); 182 | 183 | event UpdatePool(bool action, uint256 pool, address indexed lp, string name, uint256 startBlock, uint256 rewardTotal, uint256 rewardPerBlock, uint256 multiple, uint256 priority); 184 | 185 | event EndPool(uint256 pool, address indexed lp); 186 | 187 | event Stake(uint256 pool, address indexed lp, address indexed from, uint256 amount); 188 | 189 | event UpdatePower(uint256 pool, address lp, uint256 totalPower, address indexed owner, uint256 ownerInvitePower, uint256 ownerPledgePower, address indexed upper1, uint256 upper1InvitePower); 190 | 191 | event UnStake(uint256 pool, address indexed lp, address indexed to, uint256 amount); 192 | 193 | event WithdrawReward(uint256 pool, address indexed lp, address indexed to, uint256 amount); 194 | 195 | event Mint(uint256 pool, address indexed lp, uint256 amount); 196 | 197 | //////////////////////////////////////////////////////////////////////////////////// 198 | 199 | function transferOwnership(address) external; 200 | 201 | function setGameFi(ITokenGameFi) external; 202 | 203 | function setInvite(GameFiInviteV1) external; 204 | 205 | function deposit(uint256, uint256) external; 206 | 207 | function withdraw(uint256, uint256) external; 208 | 209 | function poolPledgeAddresss(uint256) external view returns (address[] memory); 210 | 211 | function powerScale(uint256, address) external view returns (uint256); 212 | 213 | function pendingReward(uint256, address) external view returns (uint256); 214 | 215 | function poolNumbers(address) external view returns (uint256[] memory); 216 | 217 | function setOperateOwner(address, bool) external; 218 | 219 | //////////////////////////////////////////////////////////////////////////////////// 220 | 221 | function addPool(string memory, address, uint256, uint256, uint256, uint256, uint256) external returns (bool); 222 | 223 | function setRewardPerBlock(uint256, uint256) external; 224 | 225 | function setRewardTotal(uint256, uint256) external; 226 | 227 | function setName(uint256, string memory) external; 228 | 229 | function setMultiple(uint256, uint256) external; 230 | 231 | function setPriority(uint256, uint256) external; 232 | 233 | //////////////////////////////////////////////////////////////////////////////////// 234 | 235 | } 236 | 237 | // File: @openzeppelin/contracts/token/ERC20/IERC20.sol 238 | 239 | 240 | pragma solidity >=0.6.0 <0.8.0; 241 | 242 | /** 243 | * @dev Interface of the ERC20 standard as defined in the EIP. 244 | */ 245 | interface IERC20 { 246 | /** 247 | * @dev Returns the amount of tokens in existence. 248 | */ 249 | function totalSupply() external view returns (uint256); 250 | 251 | /** 252 | * @dev Returns the amount of tokens owned by `account`. 253 | */ 254 | function balanceOf(address account) external view returns (uint256); 255 | 256 | /** 257 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 258 | * 259 | * Returns a boolean value indicating whether the operation succeeded. 260 | * 261 | * Emits a {Transfer} event. 262 | */ 263 | function transfer(address recipient, uint256 amount) external returns (bool); 264 | 265 | /** 266 | * @dev Returns the remaining number of tokens that `spender` will be 267 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 268 | * zero by default. 269 | * 270 | * This value changes when {approve} or {transferFrom} are called. 271 | */ 272 | function allowance(address owner, address spender) external view returns (uint256); 273 | 274 | /** 275 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 276 | * 277 | * Returns a boolean value indicating whether the operation succeeded. 278 | * 279 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 280 | * that someone may use both the old and the new allowance by unfortunate 281 | * transaction ordering. One possible solution to mitigate this race 282 | * condition is to first reduce the spender's allowance to 0 and set the 283 | * desired value afterwards: 284 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 285 | * 286 | * Emits an {Approval} event. 287 | */ 288 | function approve(address spender, uint256 amount) external returns (bool); 289 | 290 | /** 291 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 292 | * allowance mechanism. `amount` is then deducted from the caller's 293 | * allowance. 294 | * 295 | * Returns a boolean value indicating whether the operation succeeded. 296 | * 297 | * Emits a {Transfer} event. 298 | */ 299 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 300 | 301 | /** 302 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 303 | * another (`to`). 304 | * 305 | * Note that `value` may be zero. 306 | */ 307 | event Transfer(address indexed from, address indexed to, uint256 value); 308 | 309 | /** 310 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 311 | * a call to {approve}. `value` is the new allowance. 312 | */ 313 | event Approval(address indexed owner, address indexed spender, uint256 value); 314 | } 315 | 316 | // File: @openzeppelin/contracts/math/SafeMath.sol 317 | 318 | 319 | pragma solidity >=0.6.0 <0.8.0; 320 | 321 | /** 322 | * @dev Wrappers over Solidity's arithmetic operations with added overflow 323 | * checks. 324 | * 325 | * Arithmetic operations in Solidity wrap on overflow. This can easily result 326 | * in bugs, because programmers usually assume that an overflow raises an 327 | * error, which is the standard behavior in high level programming languages. 328 | * `SafeMath` restores this intuition by reverting the transaction when an 329 | * operation overflows. 330 | * 331 | * Using this library instead of the unchecked operations eliminates an entire 332 | * class of bugs, so it's recommended to use it always. 333 | */ 334 | library SafeMath { 335 | /** 336 | * @dev Returns the addition of two unsigned integers, with an overflow flag. 337 | * 338 | * _Available since v3.4._ 339 | */ 340 | function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { 341 | uint256 c = a + b; 342 | if (c < a) return (false, 0); 343 | return (true, c); 344 | } 345 | 346 | /** 347 | * @dev Returns the substraction of two unsigned integers, with an overflow flag. 348 | * 349 | * _Available since v3.4._ 350 | */ 351 | function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { 352 | if (b > a) return (false, 0); 353 | return (true, a - b); 354 | } 355 | 356 | /** 357 | * @dev Returns the multiplication of two unsigned integers, with an overflow flag. 358 | * 359 | * _Available since v3.4._ 360 | */ 361 | function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { 362 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 363 | // benefit is lost if 'b' is also tested. 364 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 365 | if (a == 0) return (true, 0); 366 | uint256 c = a * b; 367 | if (c / a != b) return (false, 0); 368 | return (true, c); 369 | } 370 | 371 | /** 372 | * @dev Returns the division of two unsigned integers, with a division by zero flag. 373 | * 374 | * _Available since v3.4._ 375 | */ 376 | function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { 377 | if (b == 0) return (false, 0); 378 | return (true, a / b); 379 | } 380 | 381 | /** 382 | * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. 383 | * 384 | * _Available since v3.4._ 385 | */ 386 | function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { 387 | if (b == 0) return (false, 0); 388 | return (true, a % b); 389 | } 390 | 391 | /** 392 | * @dev Returns the addition of two unsigned integers, reverting on 393 | * overflow. 394 | * 395 | * Counterpart to Solidity's `+` operator. 396 | * 397 | * Requirements: 398 | * 399 | * - Addition cannot overflow. 400 | */ 401 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 402 | uint256 c = a + b; 403 | require(c >= a, "SafeMath: addition overflow"); 404 | return c; 405 | } 406 | 407 | /** 408 | * @dev Returns the subtraction of two unsigned integers, reverting on 409 | * overflow (when the result is negative). 410 | * 411 | * Counterpart to Solidity's `-` operator. 412 | * 413 | * Requirements: 414 | * 415 | * - Subtraction cannot overflow. 416 | */ 417 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 418 | require(b <= a, "SafeMath: subtraction overflow"); 419 | return a - b; 420 | } 421 | 422 | /** 423 | * @dev Returns the multiplication of two unsigned integers, reverting on 424 | * overflow. 425 | * 426 | * Counterpart to Solidity's `*` operator. 427 | * 428 | * Requirements: 429 | * 430 | * - Multiplication cannot overflow. 431 | */ 432 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 433 | if (a == 0) return 0; 434 | uint256 c = a * b; 435 | require(c / a == b, "SafeMath: multiplication overflow"); 436 | return c; 437 | } 438 | 439 | /** 440 | * @dev Returns the integer division of two unsigned integers, reverting on 441 | * division by zero. The result is rounded towards zero. 442 | * 443 | * Counterpart to Solidity's `/` operator. Note: this function uses a 444 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 445 | * uses an invalid opcode to revert (consuming all remaining gas). 446 | * 447 | * Requirements: 448 | * 449 | * - The divisor cannot be zero. 450 | */ 451 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 452 | require(b > 0, "SafeMath: division by zero"); 453 | return a / b; 454 | } 455 | 456 | /** 457 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 458 | * reverting when dividing by zero. 459 | * 460 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 461 | * opcode (which leaves remaining gas untouched) while Solidity uses an 462 | * invalid opcode to revert (consuming all remaining gas). 463 | * 464 | * Requirements: 465 | * 466 | * - The divisor cannot be zero. 467 | */ 468 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 469 | require(b > 0, "SafeMath: modulo by zero"); 470 | return a % b; 471 | } 472 | 473 | /** 474 | * @dev Returns the subtraction of two unsigned integers, reverting with custom message on 475 | * overflow (when the result is negative). 476 | * 477 | * CAUTION: This function is deprecated because it requires allocating memory for the error 478 | * message unnecessarily. For custom revert reasons use {trySub}. 479 | * 480 | * Counterpart to Solidity's `-` operator. 481 | * 482 | * Requirements: 483 | * 484 | * - Subtraction cannot overflow. 485 | */ 486 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 487 | require(b <= a, errorMessage); 488 | return a - b; 489 | } 490 | 491 | /** 492 | * @dev Returns the integer division of two unsigned integers, reverting with custom message on 493 | * division by zero. The result is rounded towards zero. 494 | * 495 | * CAUTION: This function is deprecated because it requires allocating memory for the error 496 | * message unnecessarily. For custom revert reasons use {tryDiv}. 497 | * 498 | * Counterpart to Solidity's `/` operator. Note: this function uses a 499 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 500 | * uses an invalid opcode to revert (consuming all remaining gas). 501 | * 502 | * Requirements: 503 | * 504 | * - The divisor cannot be zero. 505 | */ 506 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 507 | require(b > 0, errorMessage); 508 | return a / b; 509 | } 510 | 511 | /** 512 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 513 | * reverting with custom message when dividing by zero. 514 | * 515 | * CAUTION: This function is deprecated because it requires allocating memory for the error 516 | * message unnecessarily. For custom revert reasons use {tryMod}. 517 | * 518 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 519 | * opcode (which leaves remaining gas untouched) while Solidity uses an 520 | * invalid opcode to revert (consuming all remaining gas). 521 | * 522 | * Requirements: 523 | * 524 | * - The divisor cannot be zero. 525 | */ 526 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 527 | require(b > 0, errorMessage); 528 | return a % b; 529 | } 530 | } 531 | 532 | // File: @openzeppelin/contracts/utils/Address.sol 533 | 534 | 535 | pragma solidity >=0.6.2 <0.8.0; 536 | 537 | /** 538 | * @dev Collection of functions related to the address type 539 | */ 540 | library Address { 541 | /** 542 | * @dev Returns true if `account` is a contract. 543 | * 544 | * [IMPORTANT] 545 | * ==== 546 | * It is unsafe to assume that an address for which this function returns 547 | * false is an externally-owned account (EOA) and not a contract. 548 | * 549 | * Among others, `isContract` will return false for the following 550 | * types of addresses: 551 | * 552 | * - an externally-owned account 553 | * - a contract in construction 554 | * - an address where a contract will be created 555 | * - an address where a contract lived, but was destroyed 556 | * ==== 557 | */ 558 | function isContract(address account) internal view returns (bool) { 559 | // This method relies on extcodesize, which returns 0 for contracts in 560 | // construction, since the code is only stored at the end of the 561 | // constructor execution. 562 | 563 | uint256 size; 564 | // solhint-disable-next-line no-inline-assembly 565 | assembly { size := extcodesize(account) } 566 | return size > 0; 567 | } 568 | 569 | /** 570 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 571 | * `recipient`, forwarding all available gas and reverting on errors. 572 | * 573 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 574 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 575 | * imposed by `transfer`, making them unable to receive funds via 576 | * `transfer`. {sendValue} removes this limitation. 577 | * 578 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 579 | * 580 | * IMPORTANT: because control is transferred to `recipient`, care must be 581 | * taken to not create reentrancy vulnerabilities. Consider using 582 | * {ReentrancyGuard} or the 583 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 584 | */ 585 | function sendValue(address payable recipient, uint256 amount) internal { 586 | require(address(this).balance >= amount, "Address: insufficient balance"); 587 | 588 | // solhint-disable-next-line avoid-low-level-calls, avoid-call-value 589 | (bool success, ) = recipient.call{ value: amount }(""); 590 | require(success, "Address: unable to send value, recipient may have reverted"); 591 | } 592 | 593 | /** 594 | * @dev Performs a Solidity function call using a low level `call`. A 595 | * plain`call` is an unsafe replacement for a function call: use this 596 | * function instead. 597 | * 598 | * If `target` reverts with a revert reason, it is bubbled up by this 599 | * function (like regular Solidity function calls). 600 | * 601 | * Returns the raw returned data. To convert to the expected return value, 602 | * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. 603 | * 604 | * Requirements: 605 | * 606 | * - `target` must be a contract. 607 | * - calling `target` with `data` must not revert. 608 | * 609 | * _Available since v3.1._ 610 | */ 611 | function functionCall(address target, bytes memory data) internal returns (bytes memory) { 612 | return functionCall(target, data, "Address: low-level call failed"); 613 | } 614 | 615 | /** 616 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with 617 | * `errorMessage` as a fallback revert reason when `target` reverts. 618 | * 619 | * _Available since v3.1._ 620 | */ 621 | function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { 622 | return functionCallWithValue(target, data, 0, errorMessage); 623 | } 624 | 625 | /** 626 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 627 | * but also transferring `value` wei to `target`. 628 | * 629 | * Requirements: 630 | * 631 | * - the calling contract must have an ETH balance of at least `value`. 632 | * - the called Solidity function must be `payable`. 633 | * 634 | * _Available since v3.1._ 635 | */ 636 | function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { 637 | return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); 638 | } 639 | 640 | /** 641 | * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but 642 | * with `errorMessage` as a fallback revert reason when `target` reverts. 643 | * 644 | * _Available since v3.1._ 645 | */ 646 | function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { 647 | require(address(this).balance >= value, "Address: insufficient balance for call"); 648 | require(isContract(target), "Address: call to non-contract"); 649 | 650 | // solhint-disable-next-line avoid-low-level-calls 651 | (bool success, bytes memory returndata) = target.call{ value: value }(data); 652 | return _verifyCallResult(success, returndata, errorMessage); 653 | } 654 | 655 | /** 656 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 657 | * but performing a static call. 658 | * 659 | * _Available since v3.3._ 660 | */ 661 | function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { 662 | return functionStaticCall(target, data, "Address: low-level static call failed"); 663 | } 664 | 665 | /** 666 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 667 | * but performing a static call. 668 | * 669 | * _Available since v3.3._ 670 | */ 671 | function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { 672 | require(isContract(target), "Address: static call to non-contract"); 673 | 674 | // solhint-disable-next-line avoid-low-level-calls 675 | (bool success, bytes memory returndata) = target.staticcall(data); 676 | return _verifyCallResult(success, returndata, errorMessage); 677 | } 678 | 679 | /** 680 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 681 | * but performing a delegate call. 682 | * 683 | * _Available since v3.4._ 684 | */ 685 | function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { 686 | return functionDelegateCall(target, data, "Address: low-level delegate call failed"); 687 | } 688 | 689 | /** 690 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 691 | * but performing a delegate call. 692 | * 693 | * _Available since v3.4._ 694 | */ 695 | function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { 696 | require(isContract(target), "Address: delegate call to non-contract"); 697 | 698 | // solhint-disable-next-line avoid-low-level-calls 699 | (bool success, bytes memory returndata) = target.delegatecall(data); 700 | return _verifyCallResult(success, returndata, errorMessage); 701 | } 702 | 703 | function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { 704 | if (success) { 705 | return returndata; 706 | } else { 707 | // Look for revert reason and bubble it up if present 708 | if (returndata.length > 0) { 709 | // The easiest way to bubble the revert reason is using memory via assembly 710 | 711 | // solhint-disable-next-line no-inline-assembly 712 | assembly { 713 | let returndata_size := mload(returndata) 714 | revert(add(32, returndata), returndata_size) 715 | } 716 | } else { 717 | revert(errorMessage); 718 | } 719 | } 720 | } 721 | } 722 | 723 | // File: @openzeppelin/contracts/token/ERC20/SafeERC20.sol 724 | 725 | 726 | pragma solidity >=0.6.0 <0.8.0; 727 | 728 | 729 | 730 | 731 | /** 732 | * @title SafeERC20 733 | * @dev Wrappers around ERC20 operations that throw on failure (when the token 734 | * contract returns false). Tokens that return no value (and instead revert or 735 | * throw on failure) are also supported, non-reverting calls are assumed to be 736 | * successful. 737 | * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, 738 | * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. 739 | */ 740 | library SafeERC20 { 741 | using SafeMath for uint256; 742 | using Address for address; 743 | 744 | function safeTransfer(IERC20 token, address to, uint256 value) internal { 745 | _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 746 | } 747 | 748 | function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { 749 | _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 750 | } 751 | 752 | /** 753 | * @dev Deprecated. This function has issues similar to the ones found in 754 | * {IERC20-approve}, and its usage is discouraged. 755 | * 756 | * Whenever possible, use {safeIncreaseAllowance} and 757 | * {safeDecreaseAllowance} instead. 758 | */ 759 | function safeApprove(IERC20 token, address spender, uint256 value) internal { 760 | // safeApprove should only be called when setting an initial allowance, 761 | // or when resetting it to zero. To increase and decrease it, use 762 | // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' 763 | // solhint-disable-next-line max-line-length 764 | require((value == 0) || (token.allowance(address(this), spender) == 0), 765 | "SafeERC20: approve from non-zero to non-zero allowance" 766 | ); 767 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 768 | } 769 | 770 | function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { 771 | uint256 newAllowance = token.allowance(address(this), spender).add(value); 772 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 773 | } 774 | 775 | function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { 776 | uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); 777 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 778 | } 779 | 780 | /** 781 | * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement 782 | * on the return value: the return value is optional (but if data is returned, it must not be false). 783 | * @param token The token targeted by the call. 784 | * @param data The call data (encoded using abi.encode or one of its variants). 785 | */ 786 | function _callOptionalReturn(IERC20 token, bytes memory data) private { 787 | // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since 788 | // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that 789 | // the target address contains contract code and also asserts for success in the low-level call. 790 | 791 | bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); 792 | if (returndata.length > 0) { // Return data is optional 793 | // solhint-disable-next-line max-line-length 794 | require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); 795 | } 796 | } 797 | } 798 | 799 | // File: contracts/v1-mining/implement/GameFiPoolsV1.sol 800 | 801 | 802 | pragma solidity 0.7.4; 803 | 804 | 805 | 806 | 807 | 808 | contract GameFiPoolsV1 is IGameFiPoolsV1 { 809 | 810 | using SafeMath for uint256; 811 | using SafeERC20 for IERC20; 812 | 813 | uint256 public deployBlock; 814 | address public owner; 815 | mapping(address => bool) public operateOwner; 816 | ITokenGameFi public gameFi;//gameFi contract 817 | GameFiInviteV1 public invite;//invite contract 818 | 819 | uint256 public poolCount = 0; 820 | mapping(address => RewardInfo) public rewardInfos;//User mining information 821 | mapping(uint256 => PoolInfo) public poolInfos; 822 | mapping(uint256 => PoolViewInfo) public poolViewInfos; 823 | mapping(uint256 => address[]) public pledgeAddresss; 824 | mapping(uint256 => mapping(address => UserInfo)) public pledgeUserInfo; 825 | 826 | //uint256 public constant invite1Reward = 15;//Level 1 invite rewards,15% 827 | uint256 public rewardTotal = 0;//Total mining bonus 828 | 829 | constructor (ITokenGameFi _gameFi, GameFiInviteV1 _invite) { 830 | deployBlock = block.number; 831 | owner = msg.sender; 832 | invite = _invite; 833 | _setOperateOwner(owner, true); 834 | _setGameFi(_gameFi); 835 | } 836 | 837 | //////////////////////////////////////////////////////////////////////////////////// 838 | 839 | function transferOwnership(address _owner) override external { 840 | require(owner == msg.sender, ErrorCode.FORBIDDEN); 841 | require((address(0) != _owner) && (owner != _owner), ErrorCode.INVALID_ADDRESSES); 842 | _setOperateOwner(owner, false); 843 | _setOperateOwner(_owner, true); 844 | owner = _owner; 845 | } 846 | 847 | function setGameFi(ITokenGameFi _gameFi) override external { 848 | _setGameFi(_gameFi); 849 | } 850 | 851 | function _setGameFi(ITokenGameFi _gameFi) internal { 852 | require(owner == msg.sender, ErrorCode.FORBIDDEN); 853 | gameFi = _gameFi; 854 | } 855 | 856 | function setInvite(GameFiInviteV1 _invite) override external { 857 | require(owner == msg.sender, ErrorCode.FORBIDDEN); 858 | invite = _invite; 859 | } 860 | 861 | function deposit(uint256 _pool, uint256 _amount) override external { 862 | require(0 < _amount, ErrorCode.FORBIDDEN); 863 | PoolInfo storage poolInfo = poolInfos[_pool]; 864 | require((address(0) != poolInfo.lp) && (poolInfo.startBlock <= block.number), ErrorCode.MINING_NOT_STARTED); 865 | //require(0 == poolInfo.endBlock, ErrorCode.END_OF_MINING); 866 | (, uint256 startBlock) = invite.inviteUserInfoV2(msg.sender); 867 | if (0 == startBlock) { 868 | invite.register(); 869 | 870 | emit InviteRegister(msg.sender); 871 | } 872 | 873 | IERC20(poolInfo.lp).safeTransferFrom(msg.sender, address(this), _amount); 874 | 875 | address upper1 = invite.inviteUpper1(msg.sender); 876 | 877 | computeReward(_pool); 878 | 879 | provideReward(_pool, poolInfo.rewardPerShare, poolInfo.lp, msg.sender, upper1); 880 | 881 | addPower(_pool, msg.sender, _amount, upper1); 882 | 883 | setRewardDebt(_pool, poolInfo.rewardPerShare, msg.sender, upper1); 884 | 885 | emit Stake(_pool, poolInfo.lp, msg.sender, _amount); 886 | } 887 | 888 | function withdraw(uint256 _pool, uint256 _amount) override external { 889 | PoolInfo storage poolInfo = poolInfos[_pool]; 890 | require((address(0) != poolInfo.lp) && (poolInfo.startBlock <= block.number), ErrorCode.MINING_NOT_STARTED); 891 | if (0 < _amount) { 892 | UserInfo storage userInfo = pledgeUserInfo[_pool][msg.sender]; 893 | require(_amount <= userInfo.amount, ErrorCode.BALANCE_INSUFFICIENT); 894 | } 895 | 896 | address _upper1 = invite.inviteUpper1(msg.sender); 897 | 898 | computeReward(_pool); 899 | 900 | provideReward(_pool, poolInfo.rewardPerShare, poolInfo.lp, msg.sender, _upper1); 901 | 902 | if (0 < _amount) { 903 | subPower(_pool, msg.sender, _amount, _upper1); 904 | } 905 | 906 | setRewardDebt(_pool, poolInfo.rewardPerShare, msg.sender, _upper1); 907 | 908 | if (0 < _amount) { 909 | IERC20(poolInfo.lp).safeTransfer(msg.sender, _amount); 910 | 911 | emit UnStake(_pool, poolInfo.lp, msg.sender, _amount); 912 | } 913 | } 914 | 915 | function poolPledgeAddresss(uint256 _pool) override external view returns (address[] memory) { 916 | return pledgeAddresss[_pool]; 917 | } 918 | 919 | function computeReward(uint256 _pool) internal { 920 | PoolInfo storage poolInfo = poolInfos[_pool]; 921 | if ((0 < poolInfo.totalPower) && (poolInfo.rewardProvide < poolInfo.rewardTotal)) { 922 | uint256 reward = (block.number - poolInfo.lastRewardBlock).mul(poolInfo.rewardPerBlock); 923 | if (poolInfo.rewardProvide.add(reward) > poolInfo.rewardTotal) { 924 | reward = poolInfo.rewardTotal.sub(poolInfo.rewardProvide); 925 | poolInfo.endBlock = block.number; 926 | } 927 | 928 | rewardTotal = rewardTotal.add(reward); 929 | poolInfo.rewardProvide = poolInfo.rewardProvide.add(reward); 930 | poolInfo.rewardPerShare = poolInfo.rewardPerShare.add(reward.mul(1e24).div(poolInfo.totalPower)); 931 | poolInfo.lastRewardBlock = block.number; 932 | 933 | emit Mint(_pool, poolInfo.lp, reward); 934 | 935 | if (0 < poolInfo.endBlock) { 936 | emit EndPool(_pool, poolInfo.lp); 937 | } 938 | } 939 | } 940 | 941 | function addPower(uint256 _pool, address _user, uint256 _amount, address _upper1) internal { 942 | PoolInfo storage poolInfo = poolInfos[_pool]; 943 | poolInfo.amount = poolInfo.amount.add(_amount); 944 | 945 | uint256 pledgePower = _amount; 946 | UserInfo storage userInfo = pledgeUserInfo[_pool][_user]; 947 | userInfo.amount = userInfo.amount.add(_amount); 948 | userInfo.pledgePower = userInfo.pledgePower.add(pledgePower); 949 | poolInfo.totalPower = poolInfo.totalPower.add(pledgePower); 950 | if (0 == userInfo.startBlock) { 951 | userInfo.startBlock = block.number; 952 | pledgeAddresss[_pool].push(msg.sender); 953 | } 954 | 955 | uint256 upper1InvitePower = 0; 956 | 957 | if (address(0) != _upper1 && poolInfo.invite1Reward > 0) { 958 | 959 | uint256 invite1Power = pledgePower.mul(poolInfo.invite1Reward).div(100); 960 | UserInfo storage upper1Info = pledgeUserInfo[_pool][_upper1]; 961 | upper1Info.invitePower = upper1Info.invitePower.add(invite1Power); 962 | upper1InvitePower = upper1Info.invitePower; 963 | poolInfo.totalPower = poolInfo.totalPower.add(invite1Power); 964 | if (0 == upper1Info.startBlock) { 965 | upper1Info.startBlock = block.number; 966 | pledgeAddresss[_pool].push(_upper1); 967 | } 968 | } 969 | 970 | emit UpdatePower(_pool, poolInfo.lp, poolInfo.totalPower, _user, userInfo.invitePower, userInfo.pledgePower, _upper1, upper1InvitePower); 971 | } 972 | 973 | function subPower(uint256 _pool, address _user, uint256 _amount, address _upper1) internal { 974 | PoolInfo storage poolInfo = poolInfos[_pool]; 975 | UserInfo storage userInfo = pledgeUserInfo[_pool][_user]; 976 | if (poolInfo.amount < _amount) { 977 | poolInfo.amount = 0; 978 | }else { 979 | poolInfo.amount = poolInfo.amount.sub(_amount); 980 | } 981 | 982 | uint256 pledgePower = _amount; 983 | userInfo.amount = userInfo.amount.sub(_amount); 984 | if (userInfo.pledgePower < pledgePower) { 985 | userInfo.pledgePower = 0; 986 | }else { 987 | userInfo.pledgePower = userInfo.pledgePower.sub(pledgePower); 988 | } 989 | if (poolInfo.totalPower < pledgePower) { 990 | poolInfo.totalPower = 0; 991 | }else { 992 | poolInfo.totalPower = poolInfo.totalPower.sub(pledgePower); 993 | } 994 | 995 | uint256 upper1InvitePower = 0; 996 | 997 | if (address(0) != _upper1 && poolInfo.invite1Reward > 0) { 998 | 999 | UserInfo storage upper1Info = pledgeUserInfo[_pool][_upper1]; 1000 | if (0 < upper1Info.startBlock) { 1001 | uint256 invite1Power = pledgePower.mul(poolInfo.invite1Reward).div(100); 1002 | if (upper1Info.invitePower < invite1Power) { 1003 | upper1Info.invitePower = 0; 1004 | }else { 1005 | upper1Info.invitePower = upper1Info.invitePower.sub(invite1Power); 1006 | } 1007 | upper1InvitePower = upper1Info.invitePower; 1008 | if (poolInfo.totalPower < invite1Power) { 1009 | poolInfo.totalPower = 0; 1010 | }else { 1011 | poolInfo.totalPower = poolInfo.totalPower.sub(invite1Power); 1012 | } 1013 | } 1014 | } 1015 | 1016 | emit UpdatePower(_pool, poolInfo.lp, poolInfo.totalPower, _user, userInfo.invitePower, userInfo.pledgePower, _upper1, upper1InvitePower); 1017 | } 1018 | 1019 | function provideReward(uint256 _pool, uint256 _rewardPerShare, address _lp, address _user, address _upper1) internal { 1020 | uint256 inviteReward = 0; 1021 | uint256 pledgeReward = 0; 1022 | UserInfo storage userInfo = pledgeUserInfo[_pool][_user]; 1023 | if ((0 < userInfo.invitePower) || (0 < userInfo.pledgePower)) { 1024 | inviteReward = userInfo.invitePower.mul(_rewardPerShare).sub(userInfo.inviteRewardDebt).div(1e24); 1025 | pledgeReward = userInfo.pledgePower.mul(_rewardPerShare).sub(userInfo.pledgeRewardDebt).div(1e24); 1026 | 1027 | userInfo.pendingReward = userInfo.pendingReward.add(inviteReward.add(pledgeReward)); 1028 | 1029 | RewardInfo storage userRewardInfo = rewardInfos[_user]; 1030 | userRewardInfo.inviteReward = userRewardInfo.inviteReward.add(inviteReward); 1031 | userRewardInfo.pledgeReward = userRewardInfo.pledgeReward.add(pledgeReward); 1032 | } 1033 | 1034 | if (0 < userInfo.pendingReward) { 1035 | gameFi.mint(_user, userInfo.pendingReward); 1036 | 1037 | RewardInfo storage userRewardInfo = rewardInfos[_user]; 1038 | userRewardInfo.receiveReward = userRewardInfo.inviteReward; 1039 | 1040 | emit WithdrawReward(_pool, _lp, _user, userInfo.pendingReward); 1041 | 1042 | userInfo.pendingReward = 0; 1043 | } 1044 | 1045 | if (address(0) != _upper1) { 1046 | UserInfo storage upper1Info = pledgeUserInfo[_pool][_upper1]; 1047 | if ((0 < upper1Info.invitePower) || (0 < upper1Info.pledgePower)) { 1048 | inviteReward = upper1Info.invitePower.mul(_rewardPerShare).sub(upper1Info.inviteRewardDebt).div(1e24); 1049 | pledgeReward = upper1Info.pledgePower.mul(_rewardPerShare).sub(upper1Info.pledgeRewardDebt).div(1e24); 1050 | 1051 | upper1Info.pendingReward = upper1Info.pendingReward.add(inviteReward.add(pledgeReward)); 1052 | 1053 | RewardInfo storage upper1RewardInfo = rewardInfos[_upper1]; 1054 | upper1RewardInfo.inviteReward = upper1RewardInfo.inviteReward.add(inviteReward); 1055 | upper1RewardInfo.pledgeReward = upper1RewardInfo.pledgeReward.add(pledgeReward); 1056 | } 1057 | } 1058 | } 1059 | 1060 | function setRewardDebt(uint256 _pool, uint256 _rewardPerShare, address _user, address _upper1) internal { 1061 | UserInfo storage userInfo = pledgeUserInfo[_pool][_user]; 1062 | userInfo.inviteRewardDebt = userInfo.invitePower.mul(_rewardPerShare); 1063 | userInfo.pledgeRewardDebt = userInfo.pledgePower.mul(_rewardPerShare); 1064 | 1065 | if (address(0) != _upper1) { 1066 | UserInfo storage upper1Info = pledgeUserInfo[_pool][_upper1]; 1067 | upper1Info.inviteRewardDebt = upper1Info.invitePower.mul(_rewardPerShare); 1068 | upper1Info.pledgeRewardDebt = upper1Info.pledgePower.mul(_rewardPerShare); 1069 | } 1070 | } 1071 | 1072 | function powerScale(uint256 _pool, address _user) override external view returns (uint256) { 1073 | PoolInfo memory poolInfo = poolInfos[_pool]; 1074 | if (0 == poolInfo.totalPower) { 1075 | return 0; 1076 | } 1077 | 1078 | UserInfo memory userInfo = pledgeUserInfo[_pool][_user]; 1079 | return (userInfo.invitePower.add(userInfo.pledgePower).mul(100)).div(poolInfo.totalPower); 1080 | } 1081 | 1082 | function pendingReward(uint256 _pool, address _user) override external view returns (uint256) { 1083 | uint256 totalReward = 0; 1084 | PoolInfo memory poolInfo = poolInfos[_pool]; 1085 | if (address(0) != poolInfo.lp && (poolInfo.startBlock <= block.number)) { 1086 | uint256 rewardPerShare = 0; 1087 | if (0 < poolInfo.totalPower) { 1088 | uint256 reward = (block.number - poolInfo.lastRewardBlock).mul(poolInfo.rewardPerBlock); 1089 | if (poolInfo.rewardProvide.add(reward) > poolInfo.rewardTotal) { 1090 | reward = poolInfo.rewardTotal.sub(poolInfo.rewardProvide); 1091 | } 1092 | rewardPerShare = reward.mul(1e24).div(poolInfo.totalPower); 1093 | } 1094 | rewardPerShare = rewardPerShare.add(poolInfo.rewardPerShare); 1095 | 1096 | UserInfo memory userInfo = pledgeUserInfo[_pool][_user]; 1097 | totalReward = userInfo.pendingReward; 1098 | totalReward = totalReward.add(userInfo.invitePower.mul(rewardPerShare).sub(userInfo.inviteRewardDebt).div(1e24)); 1099 | totalReward = totalReward.add(userInfo.pledgePower.mul(rewardPerShare).sub(userInfo.pledgeRewardDebt).div(1e24)); 1100 | } 1101 | 1102 | return totalReward; 1103 | } 1104 | 1105 | 1106 | 1107 | function poolNumbers(address _lp) override external view returns (uint256[] memory) { 1108 | uint256 count = 0; 1109 | for (uint256 i = 0; i < poolCount; i++) { 1110 | if (_lp == poolViewInfos[i].lp) { 1111 | count = count.add(1); 1112 | } 1113 | } 1114 | 1115 | uint256[] memory numbers = new uint256[](count); 1116 | count = 0; 1117 | for (uint256 i = 0; i < poolCount; i++) { 1118 | if (_lp == poolViewInfos[i].lp) { 1119 | numbers[count] = i; 1120 | count = count.add(1); 1121 | } 1122 | } 1123 | 1124 | return numbers; 1125 | } 1126 | 1127 | function setOperateOwner(address _address, bool _bool) override external { 1128 | _setOperateOwner(_address, _bool); 1129 | } 1130 | 1131 | function _setOperateOwner(address _address, bool _bool) internal { 1132 | require(owner == msg.sender, ErrorCode.FORBIDDEN); 1133 | operateOwner[_address] = _bool; 1134 | } 1135 | 1136 | //////////////////////////////////////////////////////////////////////////////////// 1137 | 1138 | function addPool(string memory _name, address _lp, uint256 _startBlock, uint256 _rewardTotal, uint256 _rewardPerBlock, uint256 _multiple, uint256 _invite1Reward) override external returns (bool) { 1139 | require(operateOwner[msg.sender] && (address(0) != _lp) && (address(this) != _lp), ErrorCode.FORBIDDEN); 1140 | _startBlock = _startBlock < block.number ? block.number : _startBlock; 1141 | uint256 _pool = poolCount; 1142 | poolCount = poolCount.add(1); 1143 | 1144 | PoolViewInfo storage poolViewInfo = poolViewInfos[_pool]; 1145 | poolViewInfo.lp = _lp; 1146 | poolViewInfo.name = _name; 1147 | poolViewInfo.multiple = _multiple; 1148 | poolViewInfo.priority = _pool.mul(100).add(50); 1149 | 1150 | PoolInfo storage poolInfo = poolInfos[_pool]; 1151 | poolInfo.startBlock = _startBlock; 1152 | poolInfo.rewardTotal = _rewardTotal; 1153 | poolInfo.rewardProvide = 0; 1154 | poolInfo.lp = _lp; 1155 | poolInfo.amount = 0; 1156 | poolInfo.lastRewardBlock = _startBlock.sub(1); 1157 | poolInfo.rewardPerBlock = _rewardPerBlock; 1158 | poolInfo.totalPower = 0; 1159 | poolInfo.endBlock = 0; 1160 | poolInfo.rewardPerShare = 0; 1161 | poolInfo.invite1Reward = _invite1Reward; 1162 | 1163 | emit UpdatePool(true, _pool, poolInfo.lp, poolViewInfo.name, poolInfo.startBlock, poolInfo.rewardTotal, poolInfo.rewardPerBlock, poolViewInfo.multiple, poolViewInfo.priority); 1164 | 1165 | return true; 1166 | } 1167 | 1168 | function setRewardPerBlock(uint256 _pool, uint256 _rewardPerBlock) override external { 1169 | require(operateOwner[msg.sender], ErrorCode.FORBIDDEN); 1170 | PoolInfo storage poolInfo = poolInfos[_pool]; 1171 | require((address(0) != poolInfo.lp) && (0 == poolInfo.endBlock), ErrorCode.POOL_NOT_EXIST_OR_END_OF_MINING); 1172 | 1173 | computeReward(_pool); 1174 | 1175 | poolInfo.rewardPerBlock = _rewardPerBlock; 1176 | 1177 | PoolViewInfo memory poolViewInfo = poolViewInfos[_pool]; 1178 | 1179 | emit UpdatePool(false, _pool, poolInfo.lp, poolViewInfo.name, poolInfo.startBlock, poolInfo.rewardTotal, poolInfo.rewardPerBlock, poolViewInfo.multiple, poolViewInfo.priority); 1180 | } 1181 | 1182 | function setRewardTotal(uint256 _pool, uint256 _rewardTotal) override external { 1183 | require(operateOwner[msg.sender], ErrorCode.FORBIDDEN); 1184 | PoolInfo storage poolInfo = poolInfos[_pool]; 1185 | require((address(0) != poolInfo.lp) && (0 == poolInfo.endBlock), ErrorCode.POOL_NOT_EXIST_OR_END_OF_MINING); 1186 | 1187 | computeReward(_pool); 1188 | 1189 | require(poolInfo.rewardProvide < _rewardTotal, ErrorCode.REWARDTOTAL_LESS_THAN_REWARDPROVIDE); 1190 | 1191 | poolInfo.rewardTotal = _rewardTotal; 1192 | 1193 | PoolViewInfo memory poolViewInfo = poolViewInfos[_pool]; 1194 | 1195 | emit UpdatePool(false, _pool, poolInfo.lp, poolViewInfo.name, poolInfo.startBlock, poolInfo.rewardTotal, poolInfo.rewardPerBlock, poolViewInfo.multiple, poolViewInfo.priority); 1196 | } 1197 | 1198 | function setName(uint256 _pool, string memory _name) override external { 1199 | require(operateOwner[msg.sender], ErrorCode.FORBIDDEN); 1200 | PoolViewInfo storage poolViewInfo = poolViewInfos[_pool]; 1201 | require(address(0) != poolViewInfo.lp, ErrorCode.POOL_NOT_EXIST_OR_END_OF_MINING); 1202 | poolViewInfo.name = _name; 1203 | 1204 | PoolInfo memory poolInfo = poolInfos[_pool]; 1205 | 1206 | emit UpdatePool(false, _pool, poolInfo.lp, poolViewInfo.name, poolInfo.startBlock, poolInfo.rewardTotal, poolInfo.rewardPerBlock, poolViewInfo.multiple, poolViewInfo.priority); 1207 | } 1208 | 1209 | function setMultiple(uint256 _pool, uint256 _multiple) override external { 1210 | require(operateOwner[msg.sender], ErrorCode.FORBIDDEN); 1211 | PoolViewInfo storage poolViewInfo = poolViewInfos[_pool]; 1212 | require(address(0) != poolViewInfo.lp, ErrorCode.POOL_NOT_EXIST_OR_END_OF_MINING); 1213 | poolViewInfo.multiple = _multiple; 1214 | 1215 | PoolInfo memory poolInfo = poolInfos[_pool]; 1216 | 1217 | emit UpdatePool(false, _pool, poolInfo.lp, poolViewInfo.name, poolInfo.startBlock, poolInfo.rewardTotal, poolInfo.rewardPerBlock, poolViewInfo.multiple, poolViewInfo.priority); 1218 | } 1219 | 1220 | function setPriority(uint256 _pool, uint256 _priority) override external { 1221 | require(operateOwner[msg.sender], ErrorCode.FORBIDDEN); 1222 | PoolViewInfo storage poolViewInfo = poolViewInfos[_pool]; 1223 | require(address(0) != poolViewInfo.lp, ErrorCode.POOL_NOT_EXIST_OR_END_OF_MINING); 1224 | poolViewInfo.priority = _priority; 1225 | 1226 | PoolInfo memory poolInfo = poolInfos[_pool]; 1227 | 1228 | emit UpdatePool(false, _pool, poolInfo.lp, poolViewInfo.name, poolInfo.startBlock, poolInfo.rewardTotal, poolInfo.rewardPerBlock, poolViewInfo.multiple, poolViewInfo.priority); 1229 | } 1230 | 1231 | //////////////////////////////////////////////////////////////////////////////////// 1232 | 1233 | } 1234 | -------------------------------------------------------------------------------- /GameFiToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.6.6; 3 | 4 | 5 | /* 6 | * @dev Provides information about the current execution context, including the 7 | * sender of the transaction and its data. While these are generally available 8 | * via msg.sender and msg.data, they should not be accessed in such a direct 9 | * manner, since when dealing with GSN meta-transactions the account sending and 10 | * paying for execution may not be the actual sender (as far as an application 11 | * is concerned). 12 | * 13 | * This contract is only required for intermediate, library-like contracts. 14 | */ 15 | abstract contract Context { 16 | function _msgSender() internal view virtual returns (address payable) { 17 | return msg.sender; 18 | } 19 | 20 | function _msgData() internal view virtual returns (bytes memory) { 21 | this; 22 | // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 23 | return msg.data; 24 | } 25 | } 26 | 27 | 28 | /** 29 | * @dev Contract module which provides a basic access control mechanism, where 30 | * there is an account (an owner) that can be granted exclusive access to 31 | * specific functions. 32 | * 33 | * By default, the owner account will be the one that deploys the contract. This 34 | * can later be changed with {transferOwnership}. 35 | * 36 | * This module is used through inheritance. It will make available the modifier 37 | * `onlyOwner`, which can be applied to your functions to restrict their use to 38 | * the owner. 39 | */ 40 | contract Ownable is Context { 41 | address private _owner; 42 | 43 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 44 | 45 | /** 46 | * @dev Initializes the contract setting the deployer as the initial owner. 47 | */ 48 | constructor () internal { 49 | address msgSender = _msgSender(); 50 | _owner = msgSender; 51 | emit OwnershipTransferred(address(0), msgSender); 52 | } 53 | 54 | /** 55 | * @dev Returns the address of the current owner. 56 | */ 57 | function owner() public view returns (address) { 58 | return _owner; 59 | } 60 | 61 | /** 62 | * @dev Throws if called by any account other than the owner. 63 | */ 64 | modifier onlyOwner() { 65 | require(_owner == _msgSender(), "Ownable: caller is not the owner"); 66 | _; 67 | } 68 | 69 | /** 70 | * @dev Leaves the contract without owner. It will not be possible to call 71 | * `onlyOwner` functions anymore. Can only be called by the current owner. 72 | * 73 | * NOTE: Renouncing ownership will leave the contract without an owner, 74 | * thereby removing any functionality that is only available to the owner. 75 | */ 76 | function renounceOwnership() public virtual onlyOwner { 77 | emit OwnershipTransferred(_owner, address(0)); 78 | _owner = address(0); 79 | } 80 | 81 | /** 82 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 83 | * Can only be called by the current owner. 84 | */ 85 | function transferOwnership(address newOwner) public virtual onlyOwner { 86 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 87 | emit OwnershipTransferred(_owner, newOwner); 88 | _owner = newOwner; 89 | } 90 | } 91 | 92 | 93 | /** 94 | * @dev Interface of the ERC20 standard as defined in the EIP. 95 | */ 96 | interface IERC20 { 97 | /** 98 | * @dev Returns the amount of tokens in existence. 99 | */ 100 | function totalSupply() external view returns (uint256); 101 | 102 | /** 103 | * @dev Returns the amount of tokens owned by `account`. 104 | */ 105 | function balanceOf(address account) external view returns (uint256); 106 | 107 | /** 108 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 109 | * 110 | * Returns a boolean value indicating whether the operation succeeded. 111 | * 112 | * Emits a {Transfer} event. 113 | */ 114 | function transfer(address recipient, uint256 amount) external returns (bool); 115 | 116 | /** 117 | * @dev Returns the remaining number of tokens that `spender` will be 118 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 119 | * zero by default. 120 | * 121 | * This value changes when {approve} or {transferFrom} are called. 122 | */ 123 | function allowance(address owner, address spender) external view returns (uint256); 124 | 125 | /** 126 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 127 | * 128 | * Returns a boolean value indicating whether the operation succeeded. 129 | * 130 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 131 | * that someone may use both the old and the new allowance by unfortunate 132 | * transaction ordering. One possible solution to mitigate this race 133 | * condition is to first reduce the spender's allowance to 0 and set the 134 | * desired value afterwards: 135 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 136 | * 137 | * Emits an {Approval} event. 138 | */ 139 | function approve(address spender, uint256 amount) external returns (bool); 140 | 141 | /** 142 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 143 | * allowance mechanism. `amount` is then deducted from the caller's 144 | * allowance. 145 | * 146 | * Returns a boolean value indicating whether the operation succeeded. 147 | * 148 | * Emits a {Transfer} event. 149 | */ 150 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 151 | 152 | /** 153 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 154 | * another (`to`). 155 | * 156 | * Note that `value` may be zero. 157 | */ 158 | event Transfer(address indexed from, address indexed to, uint256 value); 159 | 160 | /** 161 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 162 | * a call to {approve}. `value` is the new allowance. 163 | */ 164 | event Approval(address indexed owner, address indexed spender, uint256 value); 165 | } 166 | 167 | 168 | /** 169 | * @dev Wrappers over Solidity's arithmetic operations with added overflow 170 | * checks. 171 | * 172 | * Arithmetic operations in Solidity wrap on overflow. This can easily result 173 | * in bugs, because programmers usually assume that an overflow raises an 174 | * error, which is the standard behavior in high level programming languages. 175 | * `SafeMath` restores this intuition by reverting the transaction when an 176 | * operation overflows. 177 | * 178 | * Using this library instead of the unchecked operations eliminates an entire 179 | * class of bugs, so it's recommended to use it always. 180 | */ 181 | library SafeMath { 182 | /** 183 | * @dev Returns the addition of two unsigned integers, reverting on 184 | * overflow. 185 | * 186 | * Counterpart to Solidity's `+` operator. 187 | * 188 | * Requirements: 189 | * 190 | * - Addition cannot overflow. 191 | */ 192 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 193 | uint256 c = a + b; 194 | require(c >= a, "SafeMath: addition overflow"); 195 | 196 | return c; 197 | } 198 | 199 | /** 200 | * @dev Returns the subtraction of two unsigned integers, reverting on 201 | * overflow (when the result is negative). 202 | * 203 | * Counterpart to Solidity's `-` operator. 204 | * 205 | * Requirements: 206 | * 207 | * - Subtraction cannot overflow. 208 | */ 209 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 210 | return sub(a, b, "SafeMath: subtraction overflow"); 211 | } 212 | 213 | /** 214 | * @dev Returns the subtraction of two unsigned integers, reverting with custom message on 215 | * overflow (when the result is negative). 216 | * 217 | * Counterpart to Solidity's `-` operator. 218 | * 219 | * Requirements: 220 | * 221 | * - Subtraction cannot overflow. 222 | */ 223 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 224 | require(b <= a, errorMessage); 225 | uint256 c = a - b; 226 | 227 | return c; 228 | } 229 | 230 | /** 231 | * @dev Returns the multiplication of two unsigned integers, reverting on 232 | * overflow. 233 | * 234 | * Counterpart to Solidity's `*` operator. 235 | * 236 | * Requirements: 237 | * 238 | * - Multiplication cannot overflow. 239 | */ 240 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 241 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 242 | // benefit is lost if 'b' is also tested. 243 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 244 | if (a == 0) { 245 | return 0; 246 | } 247 | 248 | uint256 c = a * b; 249 | require(c / a == b, "SafeMath: multiplication overflow"); 250 | 251 | return c; 252 | } 253 | 254 | /** 255 | * @dev Returns the integer division of two unsigned integers. Reverts on 256 | * division by zero. The result is rounded towards zero. 257 | * 258 | * Counterpart to Solidity's `/` operator. Note: this function uses a 259 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 260 | * uses an invalid opcode to revert (consuming all remaining gas). 261 | * 262 | * Requirements: 263 | * 264 | * - The divisor cannot be zero. 265 | */ 266 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 267 | return div(a, b, "SafeMath: division by zero"); 268 | } 269 | 270 | /** 271 | * @dev Returns the integer division of two unsigned integers. Reverts with custom message on 272 | * division by zero. The result is rounded towards zero. 273 | * 274 | * Counterpart to Solidity's `/` operator. Note: this function uses a 275 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 276 | * uses an invalid opcode to revert (consuming all remaining gas). 277 | * 278 | * Requirements: 279 | * 280 | * - The divisor cannot be zero. 281 | */ 282 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 283 | require(b > 0, errorMessage); 284 | uint256 c = a / b; 285 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 286 | 287 | return c; 288 | } 289 | 290 | /** 291 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 292 | * Reverts when dividing by zero. 293 | * 294 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 295 | * opcode (which leaves remaining gas untouched) while Solidity uses an 296 | * invalid opcode to revert (consuming all remaining gas). 297 | * 298 | * Requirements: 299 | * 300 | * - The divisor cannot be zero. 301 | */ 302 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 303 | return mod(a, b, "SafeMath: modulo by zero"); 304 | } 305 | 306 | /** 307 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 308 | * Reverts with custom message when dividing by zero. 309 | * 310 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 311 | * opcode (which leaves remaining gas untouched) while Solidity uses an 312 | * invalid opcode to revert (consuming all remaining gas). 313 | * 314 | * Requirements: 315 | * 316 | * - The divisor cannot be zero. 317 | */ 318 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 319 | require(b != 0, errorMessage); 320 | return a % b; 321 | } 322 | } 323 | 324 | 325 | /** 326 | * @dev Collection of functions related to the address type 327 | */ 328 | library Address { 329 | /** 330 | * @dev Returns true if `account` is a contract. 331 | * 332 | * [IMPORTANT] 333 | * ==== 334 | * It is unsafe to assume that an address for which this function returns 335 | * false is an externally-owned account (EOA) and not a contract. 336 | * 337 | * Among others, `isContract` will return false for the following 338 | * types of addresses: 339 | * 340 | * - an externally-owned account 341 | * - a contract in construction 342 | * - an address where a contract will be created 343 | * - an address where a contract lived, but was destroyed 344 | * ==== 345 | */ 346 | function isContract(address account) internal view returns (bool) { 347 | // According to EIP-1052, 0x0 is the value returned for not-yet created accounts 348 | // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned 349 | // for accounts without code, i.e. `keccak256('')` 350 | bytes32 codehash; 351 | bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; 352 | // solhint-disable-next-line no-inline-assembly 353 | assembly {codehash := extcodehash(account)} 354 | return (codehash != accountHash && codehash != 0x0); 355 | } 356 | 357 | /** 358 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 359 | * `recipient`, forwarding all available gas and reverting on errors. 360 | * 361 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 362 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 363 | * imposed by `transfer`, making them unable to receive funds via 364 | * `transfer`. {sendValue} removes this limitation. 365 | * 366 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 367 | * 368 | * IMPORTANT: because control is transferred to `recipient`, care must be 369 | * taken to not create reentrancy vulnerabilities. Consider using 370 | * {ReentrancyGuard} or the 371 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 372 | */ 373 | function sendValue(address payable recipient, uint256 amount) internal { 374 | require(address(this).balance >= amount, "Address: insufficient balance"); 375 | 376 | // solhint-disable-next-line avoid-low-level-calls, avoid-call-value 377 | (bool success,) = recipient.call{value : amount}(""); 378 | require(success, "Address: unable to send value, recipient may have reverted"); 379 | } 380 | 381 | /** 382 | * @dev Performs a Solidity function call using a low level `call`. A 383 | * plain`call` is an unsafe replacement for a function call: use this 384 | * function instead. 385 | * 386 | * If `target` reverts with a revert reason, it is bubbled up by this 387 | * function (like regular Solidity function calls). 388 | * 389 | * Returns the raw returned data. To convert to the expected return value, 390 | * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. 391 | * 392 | * Requirements: 393 | * 394 | * - `target` must be a contract. 395 | * - calling `target` with `data` must not revert. 396 | * 397 | * _Available since v3.1._ 398 | */ 399 | function functionCall(address target, bytes memory data) internal returns (bytes memory) { 400 | return functionCall(target, data, "Address: low-level call failed"); 401 | } 402 | 403 | /** 404 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with 405 | * `errorMessage` as a fallback revert reason when `target` reverts. 406 | * 407 | * _Available since v3.1._ 408 | */ 409 | function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { 410 | return _functionCallWithValue(target, data, 0, errorMessage); 411 | } 412 | 413 | /** 414 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 415 | * but also transferring `value` wei to `target`. 416 | * 417 | * Requirements: 418 | * 419 | * - the calling contract must have an ETH balance of at least `value`. 420 | * - the called Solidity function must be `payable`. 421 | * 422 | * _Available since v3.1._ 423 | */ 424 | function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { 425 | return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); 426 | } 427 | 428 | /** 429 | * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but 430 | * with `errorMessage` as a fallback revert reason when `target` reverts. 431 | * 432 | * _Available since v3.1._ 433 | */ 434 | function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { 435 | require(address(this).balance >= value, "Address: insufficient balance for call"); 436 | return _functionCallWithValue(target, data, value, errorMessage); 437 | } 438 | 439 | function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { 440 | require(isContract(target), "Address: call to non-contract"); 441 | 442 | // solhint-disable-next-line avoid-low-level-calls 443 | (bool success, bytes memory returndata) = target.call{value : weiValue}(data); 444 | if (success) { 445 | return returndata; 446 | } else { 447 | // Look for revert reason and bubble it up if present 448 | if (returndata.length > 0) { 449 | // The easiest way to bubble the revert reason is using memory via assembly 450 | 451 | // solhint-disable-next-line no-inline-assembly 452 | assembly { 453 | let returndata_size := mload(returndata) 454 | revert(add(32, returndata), returndata_size) 455 | } 456 | } else { 457 | revert(errorMessage); 458 | } 459 | } 460 | } 461 | } 462 | 463 | 464 | /** 465 | * @dev Implementation of the {IERC20} interface. 466 | * 467 | * This implementation is agnostic to the way tokens are created. This means 468 | * that a supply mechanism has to be added in a derived contract using {_mint}. 469 | * For a generic mechanism see {ERC20PresetMinterPauser}. 470 | * 471 | * TIP: For a detailed writeup see our guide 472 | * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How 473 | * to implement supply mechanisms]. 474 | * 475 | * We have followed general OpenZeppelin guidelines: functions revert instead 476 | * of returning `false` on failure. This behavior is nonetheless conventional 477 | * and does not conflict with the expectations of ERC20 applications. 478 | * 479 | * Additionally, an {Approval} event is emitted on calls to {transferFrom}. 480 | * This allows applications to reconstruct the allowance for all accounts just 481 | * by listening to said events. Other implementations of the EIP may not emit 482 | * these events, as it isn't required by the specification. 483 | * 484 | * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} 485 | * functions have been added to mitigate the well-known issues around setting 486 | * allowances. See {IERC20-approve}. 487 | */ 488 | contract ERC20 is Context, IERC20 { 489 | using SafeMath for uint256; 490 | using Address for address; 491 | 492 | mapping(address => uint256) private _balances; 493 | 494 | mapping(address => mapping(address => uint256)) private _allowances; 495 | 496 | uint256 private _totalSupply; 497 | 498 | string private _name; 499 | string private _symbol; 500 | uint8 private _decimals; 501 | 502 | /** 503 | * @dev Sets the values for {name} and {symbol}, initializes {decimals} with 504 | * a default value of 18. 505 | * 506 | * To select a different value for {decimals}, use {_setupDecimals}. 507 | * 508 | * All three of these values are immutable: they can only be set once during 509 | * construction. 510 | */ 511 | constructor (string memory name, string memory symbol) public { 512 | _name = name; 513 | _symbol = symbol; 514 | _decimals = 18; 515 | } 516 | 517 | /** 518 | * @dev Returns the name of the token. 519 | */ 520 | function name() public view returns (string memory) { 521 | return _name; 522 | } 523 | 524 | /** 525 | * @dev Returns the symbol of the token, usually a shorter version of the 526 | * name. 527 | */ 528 | function symbol() public view returns (string memory) { 529 | return _symbol; 530 | } 531 | 532 | /** 533 | * @dev Returns the number of decimals used to get its user representation. 534 | * For example, if `decimals` equals `2`, a balance of `505` tokens should 535 | * be displayed to a user as `5,05` (`505 / 10 ** 2`). 536 | * 537 | * Tokens usually opt for a value of 18, imitating the relationship between 538 | * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is 539 | * called. 540 | * 541 | * NOTE: This information is only used for _display_ purposes: it in 542 | * no way affects any of the arithmetic of the contract, including 543 | * {IERC20-balanceOf} and {IERC20-transfer}. 544 | */ 545 | function decimals() public view returns (uint8) { 546 | return _decimals; 547 | } 548 | 549 | /** 550 | * @dev See {IERC20-totalSupply}. 551 | */ 552 | function totalSupply() public view override returns (uint256) { 553 | return _totalSupply; 554 | } 555 | 556 | /** 557 | * @dev See {IERC20-balanceOf}. 558 | */ 559 | function balanceOf(address account) public view override returns (uint256) { 560 | return _balances[account]; 561 | } 562 | 563 | /** 564 | * @dev See {IERC20-transfer}. 565 | * 566 | * Requirements: 567 | * 568 | * - `recipient` cannot be the zero address. 569 | * - the caller must have a balance of at least `amount`. 570 | */ 571 | function transfer(address recipient, uint256 amount) public virtual override returns (bool) { 572 | _transfer(_msgSender(), recipient, amount); 573 | return true; 574 | } 575 | 576 | /** 577 | * @dev See {IERC20-allowance}. 578 | */ 579 | function allowance(address owner, address spender) public view virtual override returns (uint256) { 580 | return _allowances[owner][spender]; 581 | } 582 | 583 | /** 584 | * @dev See {IERC20-approve}. 585 | * 586 | * Requirements: 587 | * 588 | * - `spender` cannot be the zero address. 589 | */ 590 | function approve(address spender, uint256 amount) public virtual override returns (bool) { 591 | _approve(_msgSender(), spender, amount); 592 | return true; 593 | } 594 | 595 | /** 596 | * @dev See {IERC20-transferFrom}. 597 | * 598 | * Emits an {Approval} event indicating the updated allowance. This is not 599 | * required by the EIP. See the note at the beginning of {ERC20}; 600 | * 601 | * Requirements: 602 | * - `sender` and `recipient` cannot be the zero address. 603 | * - `sender` must have a balance of at least `amount`. 604 | * - the caller must have allowance for ``sender``'s tokens of at least 605 | * `amount`. 606 | */ 607 | function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { 608 | _transfer(sender, recipient, amount); 609 | _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); 610 | return true; 611 | } 612 | 613 | /** 614 | * @dev Atomically increases the allowance granted to `spender` by the caller. 615 | * 616 | * This is an alternative to {approve} that can be used as a mitigation for 617 | * problems described in {IERC20-approve}. 618 | * 619 | * Emits an {Approval} event indicating the updated allowance. 620 | * 621 | * Requirements: 622 | * 623 | * - `spender` cannot be the zero address. 624 | */ 625 | function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { 626 | _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); 627 | return true; 628 | } 629 | 630 | /** 631 | * @dev Atomically decreases the allowance granted to `spender` by the caller. 632 | * 633 | * This is an alternative to {approve} that can be used as a mitigation for 634 | * problems described in {IERC20-approve}. 635 | * 636 | * Emits an {Approval} event indicating the updated allowance. 637 | * 638 | * Requirements: 639 | * 640 | * - `spender` cannot be the zero address. 641 | * - `spender` must have allowance for the caller of at least 642 | * `subtractedValue`. 643 | */ 644 | function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { 645 | _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); 646 | return true; 647 | } 648 | 649 | /** 650 | * @dev Moves tokens `amount` from `sender` to `recipient`. 651 | * 652 | * This is internal function is equivalent to {transfer}, and can be used to 653 | * e.g. implement automatic token fees, slashing mechanisms, etc. 654 | * 655 | * Emits a {Transfer} event. 656 | * 657 | * Requirements: 658 | * 659 | * - `sender` cannot be the zero address. 660 | * - `recipient` cannot be the zero address. 661 | * - `sender` must have a balance of at least `amount`. 662 | */ 663 | function _transfer(address sender, address recipient, uint256 amount) internal virtual { 664 | require(sender != address(0), "ERC20: transfer from the zero address"); 665 | require(recipient != address(0), "ERC20: transfer to the zero address"); 666 | 667 | _beforeTokenTransfer(sender, recipient, amount); 668 | 669 | _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); 670 | _balances[recipient] = _balances[recipient].add(amount); 671 | emit Transfer(sender, recipient, amount); 672 | } 673 | 674 | /** @dev Creates `amount` tokens and assigns them to `account`, increasing 675 | * the total supply. 676 | * 677 | * Emits a {Transfer} event with `from` set to the zero address. 678 | * 679 | * Requirements 680 | * 681 | * - `to` cannot be the zero address. 682 | */ 683 | function _mint(address account, uint256 amount) internal virtual { 684 | require(account != address(0), "ERC20: mint to the zero address"); 685 | 686 | _beforeTokenTransfer(address(0), account, amount); 687 | 688 | _totalSupply = _totalSupply.add(amount); 689 | _balances[account] = _balances[account].add(amount); 690 | emit Transfer(address(0), account, amount); 691 | } 692 | 693 | /** 694 | * @dev Destroys `amount` tokens from `account`, reducing the 695 | * total supply. 696 | * 697 | * Emits a {Transfer} event with `to` set to the zero address. 698 | * 699 | * Requirements 700 | * 701 | * - `account` cannot be the zero address. 702 | * - `account` must have at least `amount` tokens. 703 | */ 704 | function _burn(address account, uint256 amount) internal virtual { 705 | require(account != address(0), "ERC20: burn from the zero address"); 706 | 707 | _beforeTokenTransfer(account, address(0), amount); 708 | 709 | _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); 710 | _totalSupply = _totalSupply.sub(amount); 711 | emit Transfer(account, address(0), amount); 712 | } 713 | 714 | /** 715 | * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. 716 | * 717 | * This is internal function is equivalent to `approve`, and can be used to 718 | * e.g. set automatic allowances for certain subsystems, etc. 719 | * 720 | * Emits an {Approval} event. 721 | * 722 | * Requirements: 723 | * 724 | * - `owner` cannot be the zero address. 725 | * - `spender` cannot be the zero address. 726 | */ 727 | function _approve(address owner, address spender, uint256 amount) internal virtual { 728 | require(owner != address(0), "ERC20: approve from the zero address"); 729 | require(spender != address(0), "ERC20: approve to the zero address"); 730 | 731 | _allowances[owner][spender] = amount; 732 | emit Approval(owner, spender, amount); 733 | } 734 | 735 | /** 736 | * @dev Sets {decimals} to a value other than the default one of 18. 737 | * 738 | * WARNING: This function should only be called from the constructor. Most 739 | * applications that interact with token contracts will not expect 740 | * {decimals} to ever change, and may work incorrectly if it does. 741 | */ 742 | function _setupDecimals(uint8 decimals_) internal { 743 | _decimals = decimals_; 744 | } 745 | 746 | /** 747 | * @dev Hook that is called before any transfer of tokens. This includes 748 | * minting and burning. 749 | * 750 | * Calling conditions: 751 | * 752 | * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens 753 | * will be to transferred to `to`. 754 | * - when `from` is zero, `amount` tokens will be minted for `to`. 755 | * - when `to` is zero, `amount` of ``from``'s tokens will be burned. 756 | * - `from` and `to` are never both zero. 757 | * 758 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 759 | */ 760 | function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} 761 | } 762 | 763 | 764 | library EnumerableSet { 765 | // To implement this library for multiple types with as little code 766 | // repetition as possible, we write it in terms of a generic Set type with 767 | // bytes32 values. 768 | // The Set implementation uses private functions, and user-facing 769 | // implementations (such as AddressSet) are just wrappers around the 770 | // underlying Set. 771 | // This means that we can only create new EnumerableSets for types that fit 772 | // in bytes32. 773 | 774 | struct Set { 775 | // Storage of set values 776 | bytes32[] _values; 777 | 778 | // Position of the value in the `values` array, plus 1 because index 0 779 | // means a value is not in the set. 780 | mapping (bytes32 => uint256) _indexes; 781 | } 782 | 783 | /** 784 | * @dev Add a value to a set. O(1). 785 | * 786 | * Returns true if the value was added to the set, that is if it was not 787 | * already present. 788 | */ 789 | function _add(Set storage set, bytes32 value) private returns (bool) { 790 | if (!_contains(set, value)) { 791 | set._values.push(value); 792 | // The value is stored at length-1, but we add 1 to all indexes 793 | // and use 0 as a sentinel value 794 | set._indexes[value] = set._values.length; 795 | return true; 796 | } else { 797 | return false; 798 | } 799 | } 800 | 801 | /** 802 | * @dev Removes a value from a set. O(1). 803 | * 804 | * Returns true if the value was removed from the set, that is if it was 805 | * present. 806 | */ 807 | function _remove(Set storage set, bytes32 value) private returns (bool) { 808 | // We read and store the value's index to prevent multiple reads from the same storage slot 809 | uint256 valueIndex = set._indexes[value]; 810 | 811 | if (valueIndex != 0) { // Equivalent to contains(set, value) 812 | // To delete an element from the _values array in O(1), we swap the element to delete with the last one in 813 | // the array, and then remove the last element (sometimes called as 'swap and pop'). 814 | // This modifies the order of the array, as noted in {at}. 815 | 816 | uint256 toDeleteIndex = valueIndex - 1; 817 | uint256 lastIndex = set._values.length - 1; 818 | 819 | // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs 820 | // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. 821 | 822 | bytes32 lastvalue = set._values[lastIndex]; 823 | 824 | // Move the last value to the index where the value to delete is 825 | set._values[toDeleteIndex] = lastvalue; 826 | // Update the index for the moved value 827 | set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based 828 | 829 | // Delete the slot where the moved value was stored 830 | set._values.pop(); 831 | 832 | // Delete the index for the deleted slot 833 | delete set._indexes[value]; 834 | 835 | return true; 836 | } else { 837 | return false; 838 | } 839 | } 840 | 841 | /** 842 | * @dev Returns true if the value is in the set. O(1). 843 | */ 844 | function _contains(Set storage set, bytes32 value) private view returns (bool) { 845 | return set._indexes[value] != 0; 846 | } 847 | 848 | /** 849 | * @dev Returns the number of values on the set. O(1). 850 | */ 851 | function _length(Set storage set) private view returns (uint256) { 852 | return set._values.length; 853 | } 854 | 855 | /** 856 | * @dev Returns the value stored at position `index` in the set. O(1). 857 | * 858 | * Note that there are no guarantees on the ordering of values inside the 859 | * array, and it may change when more values are added or removed. 860 | * 861 | * Requirements: 862 | * 863 | * - `index` must be strictly less than {length}. 864 | */ 865 | function _at(Set storage set, uint256 index) private view returns (bytes32) { 866 | require(set._values.length > index, "EnumerableSet: index out of bounds"); 867 | return set._values[index]; 868 | } 869 | 870 | // Bytes32Set 871 | 872 | struct Bytes32Set { 873 | Set _inner; 874 | } 875 | 876 | /** 877 | * @dev Add a value to a set. O(1). 878 | * 879 | * Returns true if the value was added to the set, that is if it was not 880 | * already present. 881 | */ 882 | function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { 883 | return _add(set._inner, value); 884 | } 885 | 886 | /** 887 | * @dev Removes a value from a set. O(1). 888 | * 889 | * Returns true if the value was removed from the set, that is if it was 890 | * present. 891 | */ 892 | function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { 893 | return _remove(set._inner, value); 894 | } 895 | 896 | /** 897 | * @dev Returns true if the value is in the set. O(1). 898 | */ 899 | function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { 900 | return _contains(set._inner, value); 901 | } 902 | 903 | /** 904 | * @dev Returns the number of values in the set. O(1). 905 | */ 906 | function length(Bytes32Set storage set) internal view returns (uint256) { 907 | return _length(set._inner); 908 | } 909 | 910 | /** 911 | * @dev Returns the value stored at position `index` in the set. O(1). 912 | * 913 | * Note that there are no guarantees on the ordering of values inside the 914 | * array, and it may change when more values are added or removed. 915 | * 916 | * Requirements: 917 | * 918 | * - `index` must be strictly less than {length}. 919 | */ 920 | function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { 921 | return _at(set._inner, index); 922 | } 923 | 924 | // AddressSet 925 | 926 | struct AddressSet { 927 | Set _inner; 928 | } 929 | 930 | /** 931 | * @dev Add a value to a set. O(1). 932 | * 933 | * Returns true if the value was added to the set, that is if it was not 934 | * already present. 935 | */ 936 | function add(AddressSet storage set, address value) internal returns (bool) { 937 | return _add(set._inner, bytes32(uint256(value))); 938 | } 939 | 940 | /** 941 | * @dev Removes a value from a set. O(1). 942 | * 943 | * Returns true if the value was removed from the set, that is if it was 944 | * present. 945 | */ 946 | function remove(AddressSet storage set, address value) internal returns (bool) { 947 | return _remove(set._inner, bytes32(uint256(value))); 948 | } 949 | 950 | /** 951 | * @dev Returns true if the value is in the set. O(1). 952 | */ 953 | function contains(AddressSet storage set, address value) internal view returns (bool) { 954 | return _contains(set._inner, bytes32(uint256(value))); 955 | } 956 | 957 | /** 958 | * @dev Returns the number of values in the set. O(1). 959 | */ 960 | function length(AddressSet storage set) internal view returns (uint256) { 961 | return _length(set._inner); 962 | } 963 | 964 | /** 965 | * @dev Returns the value stored at position `index` in the set. O(1). 966 | * 967 | * Note that there are no guarantees on the ordering of values inside the 968 | * array, and it may change when more values are added or removed. 969 | * 970 | * Requirements: 971 | * 972 | * - `index` must be strictly less than {length}. 973 | */ 974 | function at(AddressSet storage set, uint256 index) internal view returns (address) { 975 | return address(uint256(_at(set._inner, index))); 976 | } 977 | 978 | 979 | // UintSet 980 | 981 | struct UintSet { 982 | Set _inner; 983 | } 984 | 985 | /** 986 | * @dev Add a value to a set. O(1). 987 | * 988 | * Returns true if the value was added to the set, that is if it was not 989 | * already present. 990 | */ 991 | function add(UintSet storage set, uint256 value) internal returns (bool) { 992 | return _add(set._inner, bytes32(value)); 993 | } 994 | 995 | /** 996 | * @dev Removes a value from a set. O(1). 997 | * 998 | * Returns true if the value was removed from the set, that is if it was 999 | * present. 1000 | */ 1001 | function remove(UintSet storage set, uint256 value) internal returns (bool) { 1002 | return _remove(set._inner, bytes32(value)); 1003 | } 1004 | 1005 | /** 1006 | * @dev Returns true if the value is in the set. O(1). 1007 | */ 1008 | function contains(UintSet storage set, uint256 value) internal view returns (bool) { 1009 | return _contains(set._inner, bytes32(value)); 1010 | } 1011 | 1012 | /** 1013 | * @dev Returns the number of values on the set. O(1). 1014 | */ 1015 | function length(UintSet storage set) internal view returns (uint256) { 1016 | return _length(set._inner); 1017 | } 1018 | 1019 | /** 1020 | * @dev Returns the value stored at position `index` in the set. O(1). 1021 | * 1022 | * Note that there are no guarantees on the ordering of values inside the 1023 | * array, and it may change when more values are added or removed. 1024 | * 1025 | * Requirements: 1026 | * 1027 | * - `index` must be strictly less than {length}. 1028 | */ 1029 | function at(UintSet storage set, uint256 index) internal view returns (uint256) { 1030 | return uint256(_at(set._inner, index)); 1031 | } 1032 | } 1033 | 1034 | pragma solidity ^0.6.0; 1035 | pragma experimental ABIEncoderV2; 1036 | 1037 | abstract contract DelegateERC20 is ERC20 { 1038 | // @notice A record of each accounts delegate 1039 | mapping (address => address) internal _delegates; 1040 | 1041 | /// @notice A checkpoint for marking number of votes from a given block 1042 | struct Checkpoint { 1043 | uint32 fromBlock; 1044 | uint256 votes; 1045 | } 1046 | 1047 | /// @notice A record of votes checkpoints for each account, by index 1048 | mapping (address => mapping (uint32 => Checkpoint)) public checkpoints; 1049 | 1050 | /// @notice The number of checkpoints for each account 1051 | mapping (address => uint32) public numCheckpoints; 1052 | 1053 | /// @notice The EIP-712 typehash for the contract's domain 1054 | bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); 1055 | 1056 | /// @notice The EIP-712 typehash for the delegation struct used by the contract 1057 | bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); 1058 | 1059 | /// @notice A record of states for signing / validating signatures 1060 | mapping (address => uint) public nonces; 1061 | 1062 | 1063 | // support delegates mint 1064 | function _mint(address account, uint256 amount) internal override virtual { 1065 | super._mint(account, amount); 1066 | 1067 | // add delegates to the minter 1068 | _moveDelegates(address(0), _delegates[account], amount); 1069 | } 1070 | 1071 | function _burn(address account, uint256 amount) internal override virtual { 1072 | super._burn(account, amount); 1073 | 1074 | // reduce delegates to the account 1075 | _moveDelegates(_delegates[account],address(0), amount); 1076 | } 1077 | 1078 | 1079 | function _transfer(address sender, address recipient, uint256 amount) internal override virtual { 1080 | super._transfer(sender, recipient, amount); 1081 | _moveDelegates(_delegates[sender], _delegates[recipient], amount); 1082 | } 1083 | 1084 | 1085 | /** 1086 | * @notice Delegate votes from `msg.sender` to `delegatee` 1087 | * @param delegatee The address to delegate votes to 1088 | */ 1089 | function delegate(address delegatee) external { 1090 | return _delegate(msg.sender, delegatee); 1091 | } 1092 | 1093 | /** 1094 | * @notice Delegates votes from signatory to `delegatee` 1095 | * @param delegatee The address to delegate votes to 1096 | * @param nonce The contract state required to match the signature 1097 | * @param expiry The time at which to expire the signature 1098 | * @param v The recovery byte of the signature 1099 | * @param r Half of the ECDSA signature pair 1100 | * @param s Half of the ECDSA signature pair 1101 | */ 1102 | function delegateBySig( 1103 | address delegatee, 1104 | uint nonce, 1105 | uint expiry, 1106 | uint8 v, 1107 | bytes32 r, 1108 | bytes32 s 1109 | ) 1110 | external 1111 | { 1112 | bytes32 domainSeparator = keccak256( 1113 | abi.encode( 1114 | DOMAIN_TYPEHASH, 1115 | keccak256(bytes(name())), 1116 | getChainId(), 1117 | address(this) 1118 | ) 1119 | ); 1120 | 1121 | bytes32 structHash = keccak256( 1122 | abi.encode( 1123 | DELEGATION_TYPEHASH, 1124 | delegatee, 1125 | nonce, 1126 | expiry 1127 | ) 1128 | ); 1129 | 1130 | bytes32 digest = keccak256( 1131 | abi.encodePacked( 1132 | "\x19\x01", 1133 | domainSeparator, 1134 | structHash 1135 | ) 1136 | ); 1137 | 1138 | address signatory = ecrecover(digest, v, r, s); 1139 | require(signatory != address(0), "GameFiToken::delegateBySig: invalid signature"); 1140 | require(nonce == nonces[signatory]++, "GameFiToken::delegateBySig: invalid nonce"); 1141 | require(now <= expiry, "GameFiToken::delegateBySig: signature expired"); 1142 | return _delegate(signatory, delegatee); 1143 | } 1144 | 1145 | /** 1146 | * @notice Gets the current votes balance for `account` 1147 | * @param account The address to get votes balance 1148 | * @return The number of current votes for `account` 1149 | */ 1150 | function getCurrentVotes(address account) 1151 | external 1152 | view 1153 | returns (uint256) 1154 | { 1155 | uint32 nCheckpoints = numCheckpoints[account]; 1156 | return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0; 1157 | } 1158 | 1159 | /** 1160 | * @notice Determine the prior number of votes for an account as of a block number 1161 | * @dev Block number must be a finalized block or else this function will revert to prevent misinformation. 1162 | * @param account The address of the account to check 1163 | * @param blockNumber The block number to get the vote balance at 1164 | * @return The number of votes the account had as of the given block 1165 | */ 1166 | function getPriorVotes(address account, uint blockNumber) 1167 | external 1168 | view 1169 | returns (uint256) 1170 | { 1171 | require(blockNumber < block.number, "GameFiToken::getPriorVotes: not yet determined"); 1172 | 1173 | uint32 nCheckpoints = numCheckpoints[account]; 1174 | if (nCheckpoints == 0) { 1175 | return 0; 1176 | } 1177 | 1178 | // First check most recent balance 1179 | if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) { 1180 | return checkpoints[account][nCheckpoints - 1].votes; 1181 | } 1182 | 1183 | // Next check implicit zero balance 1184 | if (checkpoints[account][0].fromBlock > blockNumber) { 1185 | return 0; 1186 | } 1187 | 1188 | uint32 lower = 0; 1189 | uint32 upper = nCheckpoints - 1; 1190 | while (upper > lower) { 1191 | uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow 1192 | Checkpoint memory cp = checkpoints[account][center]; 1193 | if (cp.fromBlock == blockNumber) { 1194 | return cp.votes; 1195 | } else if (cp.fromBlock < blockNumber) { 1196 | lower = center; 1197 | } else { 1198 | upper = center - 1; 1199 | } 1200 | } 1201 | return checkpoints[account][lower].votes; 1202 | } 1203 | 1204 | function _delegate(address delegator, address delegatee) 1205 | internal 1206 | { 1207 | address currentDelegate = _delegates[delegator]; 1208 | uint256 delegatorBalance = balanceOf(delegator); // balance of underlying balances (not scaled); 1209 | _delegates[delegator] = delegatee; 1210 | 1211 | _moveDelegates(currentDelegate, delegatee, delegatorBalance); 1212 | 1213 | emit DelegateChanged(delegator, currentDelegate, delegatee); 1214 | } 1215 | 1216 | function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal { 1217 | if (srcRep != dstRep && amount > 0) { 1218 | if (srcRep != address(0)) { 1219 | // decrease old representative 1220 | uint32 srcRepNum = numCheckpoints[srcRep]; 1221 | uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0; 1222 | uint256 srcRepNew = srcRepOld.sub(amount); 1223 | _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew); 1224 | } 1225 | 1226 | if (dstRep != address(0)) { 1227 | // increase new representative 1228 | uint32 dstRepNum = numCheckpoints[dstRep]; 1229 | uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0; 1230 | uint256 dstRepNew = dstRepOld.add(amount); 1231 | _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew); 1232 | } 1233 | } 1234 | } 1235 | 1236 | function _writeCheckpoint( 1237 | address delegatee, 1238 | uint32 nCheckpoints, 1239 | uint256 oldVotes, 1240 | uint256 newVotes 1241 | ) 1242 | internal 1243 | { 1244 | uint32 blockNumber = safe32(block.number, "GameFiToken::_writeCheckpoint: block number exceeds 32 bits"); 1245 | 1246 | if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) { 1247 | checkpoints[delegatee][nCheckpoints - 1].votes = newVotes; 1248 | } else { 1249 | checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes); 1250 | numCheckpoints[delegatee] = nCheckpoints + 1; 1251 | } 1252 | 1253 | emit DelegateVotesChanged(delegatee, oldVotes, newVotes); 1254 | } 1255 | 1256 | function safe32(uint n, string memory errorMessage) internal pure returns (uint32) { 1257 | require(n < 2**32, errorMessage); 1258 | return uint32(n); 1259 | } 1260 | 1261 | function getChainId() internal pure returns (uint) { 1262 | uint256 chainId; 1263 | assembly { chainId := chainid() } 1264 | 1265 | return chainId; 1266 | } 1267 | 1268 | /// @notice An event thats emitted when an account changes its delegate 1269 | event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); 1270 | 1271 | /// @notice An event thats emitted when a delegate account's vote balance changes 1272 | event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance); 1273 | 1274 | } 1275 | 1276 | contract GameFiToken is DelegateERC20, Ownable { 1277 | 1278 | uint256 private constant projectRDAndOperationTeamPreMineSupply = 20583529 * 1e18;//Project R&D and operation team 1279 | uint256 private constant liquidityPreMineSupply = 11435294 * 1e18;//Liquidity 1280 | uint256 private constant strategicInvestmentInstitutionPreMineSupply = 22870588 * 1e18;//Strategic Investment Institution 1281 | uint256 private constant strategicAdviserPreMineSupply = 4574118 * 1e18;//Strategic adviser 1282 | uint256 private constant ecologicalIncentivesPreMineSupply = 11435294 * 1e18;//Ecological incentives 1283 | uint256 private constant airdropPreMineSupply = 2287059 * 1e18;//Airdrop 1284 | 1285 | address private constant projectRDAndOperationTeamAddress = 0x97Dc487Be937bBed00ebF3fdccc8DBEA8033A170;//Project R&D and operation team address 1286 | address private constant liquidityAddress = 0xd8Ea5DE236Dde6ecA922F8E4DFE3DdE4Fc7CDFCe;//Liquidity address 1287 | address private constant strategicInvestmentInstitutionAddress = 0x33BD110b8a59C7e9DD5D5A22701439216B7B4661;//Strategic Investment Institution address 1288 | address private constant strategicAdviserAddress = 0xCEc92Aff7e1eFd73d8412EC33Db2851EF20F2f74;//Strategic adviser address 1289 | address private constant ecologicalIncentivesAddress = 0x304983D0214378BE6A3C4939C50895D06cc43070;//Ecological incentives address 1290 | address private constant airdropAddress = 0xD5512d99CB5A995e791D6B5C8c06e1Ca4c2d7343;//Airdrop address 1291 | 1292 | 1293 | uint256 private constant maxSupply = 228705882 * 1e18; // the total supply 1294 | uint256 public mineSupply; // the total mint 1295 | 1296 | 1297 | using EnumerableSet for EnumerableSet.AddressSet; 1298 | EnumerableSet.AddressSet private _minters; 1299 | 1300 | constructor() public ERC20("GameFi", "GFI"){ 1301 | _mint(projectRDAndOperationTeamAddress, projectRDAndOperationTeamPreMineSupply); 1302 | _mint(liquidityAddress, liquidityPreMineSupply); 1303 | _mint(strategicInvestmentInstitutionAddress, strategicInvestmentInstitutionPreMineSupply); 1304 | _mint(strategicAdviserAddress, strategicAdviserPreMineSupply); 1305 | _mint(ecologicalIncentivesAddress, ecologicalIncentivesPreMineSupply); 1306 | _mint(airdropAddress, airdropPreMineSupply); 1307 | 1308 | mineSupply = mineSupply.add(projectRDAndOperationTeamPreMineSupply).add(liquidityPreMineSupply) 1309 | .add(strategicInvestmentInstitutionPreMineSupply).add(strategicAdviserPreMineSupply).add(ecologicalIncentivesPreMineSupply) 1310 | .add(airdropPreMineSupply); 1311 | } 1312 | 1313 | // mint with max supply 1314 | function mint(address _to, uint256 _amount) public onlyMinter returns (bool) { 1315 | if (_amount.add(mineSupply) > maxSupply) { 1316 | return false; 1317 | } 1318 | _mint(_to, _amount); 1319 | mineSupply = mineSupply.add(_amount); 1320 | return true; 1321 | } 1322 | 1323 | 1324 | function burn(uint256 amount) public returns (bool){ 1325 | _burn(msg.sender, amount); 1326 | return true; 1327 | } 1328 | 1329 | function addMinter(address _addMinter) public onlyOwner returns (bool) { 1330 | require(_addMinter != address(0), "GameFiToken: _addMinter is the zero address"); 1331 | return EnumerableSet.add(_minters, _addMinter); 1332 | } 1333 | 1334 | function delMinter(address _delMinter) public onlyOwner returns (bool) { 1335 | require(_delMinter != address(0), "GameFiToken: _delMinter is the zero address"); 1336 | return EnumerableSet.remove(_minters, _delMinter); 1337 | } 1338 | 1339 | function getMinterLength() public view returns (uint256) { 1340 | return EnumerableSet.length(_minters); 1341 | } 1342 | 1343 | function isMinter(address account) public view returns (bool) { 1344 | return EnumerableSet.contains(_minters, account); 1345 | } 1346 | 1347 | function getMinter(uint256 _index) public view onlyOwner returns (address){ 1348 | require(_index <= getMinterLength() - 1, "GameFiToken: index out of bounds"); 1349 | return EnumerableSet.at(_minters, _index); 1350 | } 1351 | 1352 | // modifier for mint function 1353 | modifier onlyMinter() { 1354 | require(isMinter(msg.sender), "caller is not the minter"); 1355 | _; 1356 | } 1357 | 1358 | } 1359 | --------------------------------------------------------------------------------