github.com/DxChainNetwork/dxc@v0.8.1-0.20220824085222-1162e304b6e7/consensus/dpos/systemcontract/contracts/SystemRewards.sol (about) 1 // SPDX-License-Identifier: MIT 2 pragma solidity ^0.8.0; 3 pragma abicoder v2; 4 5 // OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol) 6 /** 7 8 * @dev Library for managing 9 10 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive 11 12 * types. 13 * 14 15 * Sets have the following properties: 16 * 17 18 * - Elements are added, removed, and checked for existence in constant time 19 20 * (O(1)). 21 22 * - Elements are enumerated in O(n). No guarantees are made on the ordering. 23 * 24 25 * ``` 26 27 ``` 28 29 * contract Example { 30 31 * // Add the library methods 32 33 * using EnumerableSet for EnumerableSet.AddressSet; 34 * 35 36 * // Declare a set state variable 37 38 * EnumerableSet.AddressSet private mySet; 39 40 * } 41 42 * ``` 43 * 44 ``` 45 46 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) 47 48 * and `uint256` (`UintSet`) are supported. 49 * 50 51 * [WARNING] 52 53 * ==== 54 55 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. 56 57 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. 58 * 59 60 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet. 61 62 * ==== 63 */ 64 library EnumerableSet { 65 // To implement this library for multiple types with as little code 66 // repetition as possible, we write it in terms of a generic Set type with 67 // bytes32 values. 68 // The Set implementation uses private functions, and user-facing 69 // implementations (such as AddressSet) are just wrappers around the 70 // underlying Set. 71 // This means that we can only create new EnumerableSets for types that fit 72 // in bytes32. 73 74 struct Set { 75 // Storage of set values 76 bytes32[] _values; 77 // Position of the value in the `values` array, plus 1 because index 0 78 // means a value is not in the set. 79 mapping(bytes32 => uint256) _indexes; 80 } 81 82 /** 83 84 * @dev Add a value to a set. O(1). 85 * 86 * Returns true if the value was added to the set, that is if it was not 87 * already present. 88 */ 89 function _add(Set storage set, bytes32 value) private returns (bool) { 90 if (!_contains(set, value)) { 91 set._values.push(value); 92 // The value is stored at length-1, but we add 1 to all indexes 93 // and use 0 as a sentinel value 94 set._indexes[value] = set._values.length; 95 return true; 96 } else { 97 return false; 98 } 99 } 100 101 /** 102 103 * @dev Removes a value from a set. O(1). 104 * 105 106 * Returns true if the value was removed from the set, that is if it was 107 108 * present. 109 */ 110 function _remove(Set storage set, bytes32 value) private returns (bool) { 111 // We read and store the value's index to prevent multiple reads from the same storage slot 112 uint256 valueIndex = set._indexes[value]; 113 114 if (valueIndex != 0) { 115 // Equivalent to contains(set, value) 116 // To delete an element from the _values array in O(1), we swap the element to delete with the last one in 117 // the array, and then remove the last element (sometimes called as 'swap and pop'). 118 // This modifies the order of the array, as noted in {at}. 119 120 uint256 toDeleteIndex = valueIndex - 1; 121 uint256 lastIndex = set._values.length - 1; 122 123 if (lastIndex != toDeleteIndex) { 124 bytes32 lastValue = set._values[lastIndex]; 125 126 // Move the last value to the index where the value to delete is 127 set._values[toDeleteIndex] = lastValue; 128 // Update the index for the moved value 129 set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex 130 } 131 132 // Delete the slot where the moved value was stored 133 set._values.pop(); 134 135 // Delete the index for the deleted slot 136 delete set._indexes[value]; 137 138 return true; 139 140 } else { 141 return false; 142 } 143 } 144 145 /** 146 147 * @dev Returns true if the value is in the set. O(1). 148 */ 149 function _contains(Set storage set, bytes32 value) 150 private 151 view 152 returns (bool) 153 { 154 return set._indexes[value] != 0; 155 } 156 157 /** 158 159 * @dev Returns the number of values on the set. O(1). 160 */ 161 function _length(Set storage set) private view returns (uint256) { 162 return set._values.length; 163 } 164 165 /** 166 167 * @dev Returns the value stored at position `index` in the set. O(1). 168 * 169 * Note that there are no guarantees on the ordering of values inside the 170 * array, and it may change when more values are added or removed. 171 * 172 * Requirements: 173 * 174 * - `index` must be strictly less than {length}. 175 */ 176 function _at(Set storage set, uint256 index) 177 private 178 view 179 returns (bytes32) 180 { 181 return set._values[index]; 182 } 183 184 /** 185 186 * @dev Return the entire set in an array 187 * 188 * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 189 * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 190 * this function has an unbounded cost, and using it as part of a state-changing function may render the function 191 * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. 192 */ 193 function _values(Set storage set) private view returns (bytes32[] memory) { 194 return set._values; 195 } 196 197 // Bytes32Set 198 199 struct Bytes32Set { 200 Set _inner; 201 } 202 203 /** 204 205 * @dev Add a value to a set. O(1). 206 * 207 * Returns true if the value was added to the set, that is if it was not 208 * already present. 209 */ 210 function add(Bytes32Set storage set, bytes32 value) 211 internal 212 returns (bool) 213 { 214 return _add(set._inner, value); 215 } 216 217 /** 218 219 * @dev Removes a value from a set. O(1). 220 * 221 * Returns true if the value was removed from the set, that is if it was 222 * present. 223 */ 224 function remove(Bytes32Set storage set, bytes32 value) 225 internal 226 returns (bool) 227 { 228 return _remove(set._inner, value); 229 } 230 231 /** 232 233 * @dev Returns true if the value is in the set. O(1). 234 */ 235 function contains(Bytes32Set storage set, bytes32 value) 236 internal 237 view 238 returns (bool) 239 { 240 return _contains(set._inner, value); 241 } 242 243 /** 244 245 * @dev Returns the number of values in the set. O(1). 246 */ 247 function length(Bytes32Set storage set) internal view returns (uint256) { 248 return _length(set._inner); 249 } 250 251 /** 252 253 * @dev Returns the value stored at position `index` in the set. O(1). 254 * 255 * Note that there are no guarantees on the ordering of values inside the 256 * array, and it may change when more values are added or removed. 257 * 258 * Requirements: 259 * 260 * - `index` must be strictly less than {length}. 261 */ 262 function at(Bytes32Set storage set, uint256 index) 263 internal 264 view 265 returns (bytes32) 266 { 267 return _at(set._inner, index); 268 } 269 270 /** 271 272 * @dev Return the entire set in an array 273 * 274 * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 275 * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 276 * this function has an unbounded cost, and using it as part of a state-changing function may render the function 277 * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. 278 */ 279 function values(Bytes32Set storage set) 280 internal 281 view 282 returns (bytes32[] memory) 283 { 284 return _values(set._inner); 285 } 286 287 // AddressSet 288 289 struct AddressSet { 290 Set _inner; 291 } 292 293 /** 294 295 * @dev Add a value to a set. O(1). 296 * 297 * Returns true if the value was added to the set, that is if it was not 298 * already present. 299 */ 300 function add(AddressSet storage set, address value) 301 internal 302 returns (bool) 303 { 304 return _add(set._inner, bytes32(uint256(uint160(value)))); 305 } 306 307 /** 308 309 * @dev Removes a value from a set. O(1). 310 * 311 * Returns true if the value was removed from the set, that is if it was 312 * present. 313 */ 314 function remove(AddressSet storage set, address value) 315 internal 316 returns (bool) 317 { 318 return _remove(set._inner, bytes32(uint256(uint160(value)))); 319 } 320 321 /** 322 323 * @dev Returns true if the value is in the set. O(1). 324 */ 325 function contains(AddressSet storage set, address value) 326 internal 327 view 328 returns (bool) 329 { 330 return _contains(set._inner, bytes32(uint256(uint160(value)))); 331 } 332 333 /** 334 335 * @dev Returns the number of values in the set. O(1). 336 */ 337 function length(AddressSet storage set) internal view returns (uint256) { 338 return _length(set._inner); 339 } 340 341 /** 342 343 * @dev Returns the value stored at position `index` in the set. O(1). 344 * 345 * Note that there are no guarantees on the ordering of values inside the 346 * array, and it may change when more values are added or removed. 347 * 348 * Requirements: 349 * 350 * - `index` must be strictly less than {length}. 351 */ 352 function at(AddressSet storage set, uint256 index) 353 internal 354 view 355 returns (address) 356 { 357 return address(uint160(uint256(_at(set._inner, index)))); 358 } 359 360 /** 361 362 * @dev Return the entire set in an array 363 * 364 365 * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 366 367 * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 368 369 * this function has an unbounded cost, and using it as part of a state-changing function may render the function 370 371 * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. 372 */ 373 function values(AddressSet storage set) 374 internal 375 view 376 returns (address[] memory) 377 { 378 bytes32[] memory store = _values(set._inner); 379 address[] memory result; 380 381 /// @solidity memory-safe-assembly 382 assembly { 383 result := store 384 } 385 386 return result; 387 } 388 389 // UintSet 390 391 struct UintSet { 392 Set _inner; 393 } 394 395 /** 396 397 * @dev Add a value to a set. O(1). 398 * 399 * Returns true if the value was added to the set, that is if it was not 400 * already present. 401 */ 402 function add(UintSet storage set, uint256 value) internal returns (bool) { 403 return _add(set._inner, bytes32(value)); 404 } 405 406 /** 407 408 * @dev Removes a value from a set. O(1). 409 * 410 * Returns true if the value was removed from the set, that is if it was 411 * present. 412 */ 413 function remove(UintSet storage set, uint256 value) 414 internal 415 returns (bool) 416 { 417 return _remove(set._inner, bytes32(value)); 418 } 419 420 /** 421 422 * @dev Returns true if the value is in the set. O(1). 423 */ 424 function contains(UintSet storage set, uint256 value) 425 internal 426 view 427 returns (bool) 428 { 429 return _contains(set._inner, bytes32(value)); 430 } 431 432 /** 433 434 * @dev Returns the number of values on the set. O(1). 435 */ 436 function length(UintSet storage set) internal view returns (uint256) { 437 return _length(set._inner); 438 } 439 440 /** 441 442 * @dev Returns the value stored at position `index` in the set. O(1). 443 * 444 * Note that there are no guarantees on the ordering of values inside the 445 * array, and it may change when more values are added or removed. 446 * 447 * Requirements: 448 * 449 * - `index` must be strictly less than {length}. 450 */ 451 function at(UintSet storage set, uint256 index) 452 internal 453 view 454 returns (uint256) 455 { 456 return uint256(_at(set._inner, index)); 457 } 458 459 /** 460 461 * @dev Return the entire set in an array 462 * 463 464 * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed 465 466 * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that 467 468 * this function has an unbounded cost, and using it as part of a state-changing function may render the function 469 470 * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. 471 */ 472 function values(UintSet storage set) 473 internal 474 view 475 returns (uint256[] memory) 476 { 477 bytes32[] memory store = _values(set._inner); 478 uint256[] memory result; 479 480 /// @solidity memory-safe-assembly 481 assembly { 482 result := store 483 } 484 485 return result; 486 } 487 } 488 489 // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) 490 /** 491 492 * @dev Collection of functions related to the address type 493 */ 494 library Address { 495 /** 496 497 * @dev Returns true if `account` is a contract. 498 * 499 500 * [IMPORTANT] 501 502 * ==== 503 504 * It is unsafe to assume that an address for which this function returns 505 506 * false is an externally-owned account (EOA) and not a contract. 507 * 508 509 * Among others, `isContract` will return false for the following 510 511 * types of addresses: 512 * 513 514 * - an externally-owned account 515 516 * - a contract in construction 517 518 * - an address where a contract will be created 519 520 * - an address where a contract lived, but was destroyed 521 522 * ==== 523 * 524 525 * [IMPORTANT] 526 527 * ==== 528 529 * You shouldn't rely on `isContract` to protect against flash loan attacks! 530 * 531 532 * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets 533 534 * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract 535 536 * constructor. 537 538 * ==== 539 */ 540 function isContract(address account) internal view returns (bool) { 541 // This method relies on extcodesize/address.code.length, which returns 0 542 // for contracts in construction, since the code is only stored at the end 543 // of the constructor execution. 544 545 return account.code.length > 0; 546 } 547 548 /** 549 550 * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 551 552 * `recipient`, forwarding all available gas and reverting on errors. 553 * 554 555 * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 556 557 * of certain opcodes, possibly making contracts go over the 2300 gas limit 558 559 * imposed by `transfer`, making them unable to receive funds via 560 561 * `transfer`. {sendValue} removes this limitation. 562 * 563 564 * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 565 * 566 567 * IMPORTANT: because control is transferred to `recipient`, care must be 568 569 * taken to not create reentrancy vulnerabilities. Consider using 570 571 * {ReentrancyGuard} or the 572 573 * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 574 */ 575 function sendValue(address payable recipient, uint256 amount) internal { 576 require( 577 address(this).balance >= amount, 578 "Address: insufficient balance" 579 ); 580 581 (bool success, ) = recipient.call{value: amount}(""); 582 require( 583 success, 584 "Address: unable to send value, recipient may have reverted" 585 ); 586 } 587 588 /** 589 590 * @dev Performs a Solidity function call using a low level `call`. A 591 * plain `call` is an unsafe replacement for a function call: use this 592 * function instead. 593 * 594 * If `target` reverts with a revert reason, it is bubbled up by this 595 * function (like regular Solidity function calls). 596 * 597 * Returns the raw returned data. To convert to the expected return value, 598 * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. 599 * 600 * Requirements: 601 * 602 * - `target` must be a contract. 603 * - calling `target` with `data` must not revert. 604 * 605 * _Available since v3.1._ 606 */ 607 function functionCall(address target, bytes memory data) 608 internal 609 returns (bytes memory) 610 { 611 return functionCall(target, data, "Address: low-level call failed"); 612 } 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( 622 address target, 623 bytes memory data, 624 string memory errorMessage 625 ) internal returns (bytes memory) { 626 return functionCallWithValue(target, data, 0, errorMessage); 627 } 628 629 /** 630 631 * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 632 * but also transferring `value` wei to `target`. 633 * 634 * Requirements: 635 * 636 * - the calling contract must have an ETH balance of at least `value`. 637 * - the called Solidity function must be `payable`. 638 * 639 * _Available since v3.1._ 640 */ 641 function functionCallWithValue( 642 address target, 643 bytes memory data, 644 uint256 value 645 ) internal returns (bytes memory) { 646 return 647 functionCallWithValue( 648 target, 649 data, 650 value, 651 "Address: low-level call with value failed" 652 ); 653 } 654 655 /** 656 657 * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but 658 659 * with `errorMessage` as a fallback revert reason when `target` reverts. 660 * 661 662 * _Available since v3.1._ 663 */ 664 function functionCallWithValue( 665 address target, 666 bytes memory data, 667 uint256 value, 668 string memory errorMessage 669 ) internal returns (bytes memory) { 670 require( 671 address(this).balance >= value, 672 "Address: insufficient balance for call" 673 ); 674 require(isContract(target), "Address: call to non-contract"); 675 676 (bool success, bytes memory returndata) = target.call{value: value}( 677 data 678 ); 679 return verifyCallResult(success, returndata, errorMessage); 680 } 681 682 /** 683 684 * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 685 * but performing a static call. 686 * 687 * _Available since v3.3._ 688 */ 689 function functionStaticCall(address target, bytes memory data) 690 internal 691 view 692 returns (bytes memory) 693 { 694 return 695 functionStaticCall( 696 target, 697 data, 698 "Address: low-level static call failed" 699 ); 700 } 701 702 /** 703 704 * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 705 706 * but performing a static call. 707 * 708 709 * _Available since v3.3._ 710 */ 711 function functionStaticCall( 712 address target, 713 bytes memory data, 714 string memory errorMessage 715 ) internal view returns (bytes memory) { 716 require(isContract(target), "Address: static call to non-contract"); 717 718 (bool success, bytes memory returndata) = target.staticcall(data); 719 return verifyCallResult(success, returndata, errorMessage); 720 } 721 722 /** 723 724 * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 725 * but performing a delegate call. 726 * 727 * _Available since v3.4._ 728 */ 729 function functionDelegateCall(address target, bytes memory data) 730 internal 731 returns (bytes memory) 732 { 733 return 734 functionDelegateCall( 735 target, 736 data, 737 "Address: low-level delegate call failed" 738 ); 739 } 740 741 /** 742 743 * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 744 745 * but performing a delegate call. 746 * 747 748 * _Available since v3.4._ 749 */ 750 function functionDelegateCall( 751 address target, 752 bytes memory data, 753 string memory errorMessage 754 ) internal returns (bytes memory) { 755 require(isContract(target), "Address: delegate call to non-contract"); 756 757 (bool success, bytes memory returndata) = target.delegatecall(data); 758 return verifyCallResult(success, returndata, errorMessage); 759 } 760 761 /** 762 763 * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the 764 * revert reason using the provided one. 765 * 766 * _Available since v4.3._ 767 */ 768 function verifyCallResult( 769 bool success, 770 bytes memory returndata, 771 string memory errorMessage 772 ) internal pure returns (bytes memory) { 773 if (success) { 774 return returndata; 775 } else { 776 // Look for revert reason and bubble it up if present 777 if (returndata.length > 0) { 778 // The easiest way to bubble the revert reason is using memory via assembly 779 /// @solidity memory-safe-assembly 780 assembly { 781 let returndata_size := mload(returndata) 782 revert(add(32, returndata), returndata_size) 783 } 784 } else { 785 revert(errorMessage); 786 } 787 } 788 } 789 } 790 791 // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) 792 /** 793 794 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed 795 796 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an 797 798 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer 799 800 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. 801 * 802 803 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be 804 805 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in 806 807 * case an upgrade adds a module that needs to be initialized. 808 * 809 810 * For example: 811 * 812 813 * [.hljs-theme-light.nopadding] 814 815 * ``` 816 817 ``` 818 819 * contract MyToken is ERC20Upgradeable { 820 821 * function initialize() initializer public { 822 823 * __ERC20_init("MyToken", "MTK"); 824 825 * } 826 827 * } 828 829 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { 830 831 * function initializeV2() reinitializer(2) public { 832 833 * __ERC20Permit_init("MyToken"); 834 835 * } 836 837 * } 838 839 * ``` 840 * 841 ``` 842 843 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as 844 845 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. 846 * 847 848 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure 849 850 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. 851 * 852 853 * [CAUTION] 854 855 * ==== 856 857 * Avoid leaving a contract uninitialized. 858 * 859 860 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation 861 862 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke 863 864 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: 865 * 866 867 * [.hljs-theme-light.nopadding] 868 869 * ``` 870 871 ``` 872 873 * /// @custom:oz-upgrades-unsafe-allow constructor 874 875 * constructor() { 876 877 * _disableInitializers(); 878 879 * } 880 881 * ``` 882 883 ``` 884 885 * ==== 886 */ 887 abstract contract Initializable { 888 /** 889 890 * @dev Indicates that the contract has been initialized. 891 * @custom:oz-retyped-from bool 892 */ 893 uint8 private _initialized; 894 895 /** 896 897 * @dev Indicates that the contract is in the process of being initialized. 898 */ 899 bool private _initializing; 900 901 /** 902 903 * @dev Triggered when the contract has been initialized or reinitialized. 904 */ 905 event Initialized(uint8 version); 906 907 /** 908 909 * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, 910 * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. 911 */ 912 modifier initializer() { 913 bool isTopLevelCall = !_initializing; 914 require( 915 (isTopLevelCall && _initialized < 1) || 916 (!Address.isContract(address(this)) && _initialized == 1), 917 "Initializable: contract is already initialized" 918 ); 919 _initialized = 1; 920 if (isTopLevelCall) { 921 _initializing = true; 922 } 923 _; 924 if (isTopLevelCall) { 925 _initializing = false; 926 emit Initialized(1); 927 } 928 } 929 930 /** 931 932 * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the 933 * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be 934 * used to initialize parent contracts. 935 * 936 * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original 937 * initialization step. This is essential to configure modules that are added through upgrades and that require 938 * initialization. 939 * 940 * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in 941 * a contract, executing them in the right order is up to the developer or operator. 942 */ 943 modifier reinitializer(uint8 version) { 944 require( 945 !_initializing && _initialized < version, 946 "Initializable: contract is already initialized" 947 ); 948 _initialized = version; 949 _initializing = true; 950 _; 951 _initializing = false; 952 emit Initialized(version); 953 } 954 955 /** 956 957 * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the 958 * {initializer} and {reinitializer} modifiers, directly or indirectly. 959 */ 960 modifier onlyInitializing() { 961 require(_initializing, "Initializable: contract is not initializing"); 962 _; 963 } 964 965 /** 966 967 * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. 968 * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized 969 * to any version. It is recommended to use this to lock implementation contracts that are designed to be called 970 * through proxies. 971 */ 972 function _disableInitializers() internal virtual { 973 require(!_initializing, "Initializable: contract is initializing"); 974 if (_initialized < type(uint8).max) { 975 _initialized = type(uint8).max; 976 emit Initialized(type(uint8).max); 977 } 978 } 979 } 980 981 // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) 982 /** 983 984 * @dev Contract module that helps prevent reentrant calls to a function. 985 * 986 987 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier 988 989 * available, which can be applied to functions to make sure there are no nested 990 991 * (reentrant) calls to them. 992 * 993 994 * Note that because there is a single `nonReentrant` guard, functions marked as 995 996 * `nonReentrant` may not call one another. This can be worked around by making 997 998 * those functions `private`, and then adding `external` `nonReentrant` entry 999 1000 * points to them. 1001 * 1002 1003 * TIP: If you would like to learn more about reentrancy and alternative ways 1004 1005 * to protect against it, check out our blog post 1006 1007 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. 1008 */ 1009 abstract contract ReentrancyGuard { 1010 // Booleans are more expensive than uint256 or any type that takes up a full 1011 // word because each write operation emits an extra SLOAD to first read the 1012 // slot's contents, replace the bits taken up by the boolean, and then write 1013 // back. This is the compiler's defense against contract upgrades and 1014 // pointer aliasing, and it cannot be disabled. 1015 1016 // The values being non-zero value makes deployment a bit more expensive, 1017 // but in exchange the refund on every call to nonReentrant will be lower in 1018 // amount. Since refunds are capped to a percentage of the total 1019 // transaction's gas, it is best to keep them low in cases like this one, to 1020 // increase the likelihood of the full refund coming into effect. 1021 uint256 private constant _NOT_ENTERED = 1; 1022 uint256 private constant _ENTERED = 2; 1023 1024 uint256 private _status; 1025 1026 constructor() { 1027 _status = _NOT_ENTERED; 1028 } 1029 1030 /** 1031 1032 * @dev Prevents a contract from calling itself, directly or indirectly. 1033 1034 * Calling a `nonReentrant` function from another `nonReentrant` 1035 1036 * function is not supported. It is possible to prevent this from happening 1037 1038 * by making the `nonReentrant` function external, and making it call a 1039 1040 * `private` function that does the actual work. 1041 */ 1042 modifier nonReentrant() { 1043 // On the first call to nonReentrant, _notEntered will be true 1044 require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); 1045 1046 // Any calls to nonReentrant after this point will fail 1047 _status = _ENTERED; 1048 1049 _; 1050 1051 // By storing the original value once again, a refund is triggered (see 1052 // https://eips.ethereum.org/EIPS/eip-2200) 1053 _status = _NOT_ENTERED; 1054 } 1055 } 1056 1057 contract Base { 1058 uint256 public constant BLOCK_SECONDS = 6; 1059 /// @notice min rate. base on 100 1060 uint8 public constant MIN_RATE = 70; 1061 /// @notice max rate. base on 100 1062 uint8 public constant MAX_RATE = 100; 1063 1064 /// @notice 10 * 60 / BLOCK_SECONDS 1065 uint256 public constant EPOCH_BLOCKS = 14400; 1066 /// @notice min deposit for validator 1067 uint256 public constant MIN_DEPOSIT = 4e7 ether; 1068 uint256 public constant MAX_PUNISH_COUNT = 139; 1069 1070 /// @notice use blocks as units in code: RATE_SET_LOCK_EPOCHS * EPOCH_BLOCKS 1071 uint256 public constant RATE_SET_LOCK_EPOCHS = 1; 1072 /// @notice use blocks as units in code: VALIDATOR_UNSTAKE_LOCK_EPOCHS * EPOCH_BLOCKS 1073 uint256 public constant VALIDATOR_UNSTAKE_LOCK_EPOCHS = 1; 1074 /// @notice use blocks as units in code: PROPOSAL_DURATION_EPOCHS * EPOCH_BLOCKS 1075 uint256 public constant PROPOSAL_DURATION_EPOCHS = 7; 1076 /// @notice use epoch as units in code: VALIDATOR_REWARD_LOCK_EPOCHS 1077 uint256 public constant VALIDATOR_REWARD_LOCK_EPOCHS = 7; 1078 /// @notice use epoch as units in code: VOTE_CANCEL_EPOCHS 1079 uint256 public constant VOTE_CANCEL_EPOCHS = 1; 1080 1081 uint256 public constant MAX_VALIDATORS_COUNT = 210; 1082 uint256 public constant MAX_VALIDATOR_DETAIL_LENGTH = 1000; 1083 uint256 public constant MAX_VALIDATOR_NAME_LENGTH = 100; 1084 1085 // total deposit 1086 uint256 public constant TOTAL_DEPOSIT_LV1 = 1e18 * 1e8 * 150; 1087 uint256 public constant TOTAL_DEPOSIT_LV2 = 1e18 * 1e8 * 200; 1088 uint256 public constant TOTAL_DEPOSIT_LV3 = 1e18 * 1e8 * 250; 1089 uint256 public constant TOTAL_DEPOSIT_LV4 = 1e18 * 1e8 * 300; 1090 uint256 public constant TOTAL_DEPOSIT_LV5 = 1e18 * 1e8 * 350; 1091 1092 // block reward 1093 uint256 public constant REWARD_DEPOSIT_UNDER_LV1 = 1e15 * 95250; 1094 uint256 public constant REWARD_DEPOSIT_FROM_LV1_TO_LV2 = 1e15 * 128250; 1095 uint256 public constant REWARD_DEPOSIT_FROM_LV2_TO_LV3 = 1e15 * 157125; 1096 uint256 public constant REWARD_DEPOSIT_FROM_LV3_TO_LV4 = 1e15 * 180750; 1097 uint256 public constant REWARD_DEPOSIT_FROM_LV4_TO_LV5 = 1e15 * 199875; 1098 uint256 public constant REWARD_DEPOSIT_OVER_LV5 = 1e15 * 214125; 1099 1100 // validator count 1101 uint256 public constant MAX_VALIDATOR_COUNT_LV1 = 21; 1102 uint256 public constant MAX_VALIDATOR_COUNT_LV2 = 33; 1103 uint256 public constant MAX_VALIDATOR_COUNT_LV3 = 66; 1104 uint256 public constant MAX_VALIDATOR_COUNT_LV4 = 99; 1105 uint256 public constant MIN_LEVEL_VALIDATOR_COUNT = 60; 1106 uint256 public constant MEDIUM_LEVEL_VALIDATOR_COUNT = 90; 1107 uint256 public constant MAX_LEVEL_VALIDATOR_COUNT = 120; 1108 1109 // dead address 1110 address public constant BLACK_HOLE_ADDRESS = 1111 0x0000000000000000000000000000000000000000; 1112 1113 uint256 public constant SAFE_MULTIPLIER = 1e18; 1114 1115 modifier onlySystem() { 1116 require(tx.gasprice == 0, "Prohibit external calls"); 1117 _; 1118 } 1119 1120 modifier onlyMiner() { 1121 require(msg.sender == block.coinbase, "msg.sender error"); 1122 _; 1123 } 1124 1125 /** 1126 * @dev return current epoch 1127 */ 1128 function currentEpoch() public view returns (uint256) { 1129 return block.number / EPOCH_BLOCKS; 1130 } 1131 1132 } 1133 1134 interface ISystemRewards { 1135 function epochs(uint256 _epoch) 1136 external 1137 view 1138 returns ( 1139 uint256, 1140 uint256, 1141 uint256, 1142 uint256 1143 ); 1144 1145 function updateValidatorWhileElect( 1146 address _val, 1147 uint8 _rate, 1148 uint256 _newEpoch 1149 ) external; 1150 1151 function updateEpochWhileElect( 1152 uint256 _tvl, 1153 uint256 _valCount, 1154 uint256 _effictiveValCount, 1155 uint256 _newEpoch 1156 ) external; 1157 1158 function updateValidatorWhileEpochEnd(address _val, uint256 _votes) 1159 external; 1160 1161 function getRewardPerVote(address _val) external view returns (uint256); 1162 1163 } 1164 1165 interface IProposals {} 1166 1167 interface INodeVote { 1168 function totalVotes() external view returns (uint256); 1169 } 1170 1171 contract Validators is Base, Initializable, ReentrancyGuard { 1172 using EnumerableSet for EnumerableSet.AddressSet; 1173 using Address for address; 1174 1175 enum ValidatorStatus { 1176 canceled, 1177 canceling, 1178 cancelQueue, 1179 kickout, 1180 effictive 1181 } 1182 1183 address[] public curEpochValidators; 1184 mapping(address => uint256) public curEpochValidatorsIdMap; 1185 1186 EnumerableSet.AddressSet effictiveValidators; 1187 1188 /// @notice canceled、canceling、kickout 1189 EnumerableSet.AddressSet invalidValidators; 1190 1191 struct Validator { 1192 ValidatorStatus status; 1193 uint256 deposit; 1194 uint8 rate; 1195 /// @notice name 1196 string name; 1197 /// @notice details 1198 string details; 1199 uint256 votes; 1200 uint256 unstakeLockingEndBlock; 1201 uint256 rateSettLockingEndBlock; 1202 } 1203 1204 mapping(address => Validator) _validators; 1205 1206 mapping(address => EnumerableSet.AddressSet) validatorToVoters; 1207 1208 /// @notice all validators deposit 1209 uint256 public totalDeposit; 1210 1211 /// @notice cancel validator queue 1212 EnumerableSet.AddressSet cancelingValidators; 1213 1214 /// @notice SystemRewards contract 1215 ISystemRewards public sysRewards; 1216 1217 /// @notice Proposals contract 1218 IProposals public proposals; 1219 1220 /// @notice NodeVote contract 1221 INodeVote public nodeVote; 1222 1223 event LogAddValidator( 1224 address indexed _val, 1225 uint256 _deposit, 1226 uint256 _rate 1227 ); 1228 event LogUpdateValidatorDeposit(address indexed _val, uint256 _deposit); 1229 event LogUpdateValidatorRate( 1230 address indexed _val, 1231 uint8 _preRate, 1232 uint8 _rate 1233 ); 1234 event LogUnstakeValidator(address indexed _val); 1235 event LogRedeemValidator(address indexed _val); 1236 event LogRestoreValidator(address indexed _val); 1237 1238 /** 1239 * @dev only Proposals contract address 1240 */ 1241 modifier onlyProposalsC() { 1242 require( 1243 msg.sender == address(proposals), 1244 "Validators: not Proposals contract address" 1245 ); 1246 _; 1247 } 1248 1249 /** 1250 * @dev only SystemRewards contract address 1251 */ 1252 modifier onlySysRewardsC() { 1253 require( 1254 msg.sender == address(sysRewards), 1255 "Validators: not SystemRewards contract address" 1256 ); 1257 _; 1258 } 1259 1260 /** 1261 * @dev only NodeVote contract address 1262 */ 1263 modifier onlyNodeVoteC() { 1264 require( 1265 msg.sender == address(nodeVote), 1266 "Validators: not NodeVote contract address" 1267 ); 1268 _; 1269 } 1270 1271 function initialize( 1272 address _proposal, 1273 address _sysReward, 1274 address _nodeVote, 1275 address _initVal, 1276 uint256 _initDeposit, 1277 uint8 _initRate, 1278 string memory _name, 1279 string memory _details 1280 ) external payable onlySystem initializer { 1281 sysRewards = ISystemRewards(_sysReward); 1282 proposals = IProposals(_proposal); 1283 nodeVote = INodeVote(_nodeVote); 1284 1285 require(!_initVal.isContract(), "Validators: validator address error"); 1286 require( 1287 msg.value == _initDeposit && _initDeposit >= MIN_DEPOSIT, 1288 "Validators: deposit or value error" 1289 ); 1290 require( 1291 _initRate >= MIN_RATE && _initRate <= MAX_RATE, 1292 "Validators: Rate must greater than MIN_RATE and less than MAX_RATE" 1293 ); 1294 1295 Validator storage val = _validators[_initVal]; 1296 val.status = ValidatorStatus.effictive; 1297 val.deposit = _initDeposit; 1298 val.rate = _initRate; 1299 val.name = _name; 1300 val.details = _details; 1301 1302 effictiveValidators.add(_initVal); 1303 totalDeposit += _initDeposit; 1304 1305 curEpochValidators.push(_initVal); 1306 curEpochValidatorsIdMap[_initVal] = curEpochValidators.length; 1307 1308 uint256 curEpoch = currentEpoch(); 1309 sysRewards.updateValidatorWhileElect(_initVal, _initRate, curEpoch); 1310 sysRewards.updateEpochWhileElect( 1311 totalDeposit, 1312 curEpochValidators.length, 1313 effictiveValidators.length(), 1314 curEpoch 1315 ); 1316 1317 emit LogAddValidator(_initVal, _initDeposit, _initRate); 1318 } 1319 1320 /** 1321 * @dev get voter 1322 */ 1323 function getValidatorVoters( 1324 address _val, 1325 uint256 page, 1326 uint256 size 1327 ) external view returns (address[] memory) { 1328 require(page > 0 && size > 0, "Validators: Requests param error"); 1329 EnumerableSet.AddressSet storage voters = validatorToVoters[_val]; 1330 uint256 start = (page - 1) * size; 1331 if (voters.length() < start) { 1332 size = 0; 1333 } else { 1334 uint256 length = voters.length() - start; 1335 if (length < size) { 1336 size = length; 1337 } 1338 } 1339 1340 address[] memory vals = new address[](size); 1341 for (uint256 i = 0; i < size; i++) { 1342 vals[i] = voters.at(i + start); 1343 } 1344 return vals; 1345 } 1346 1347 /** 1348 * @dev return voters count of validator 1349 */ 1350 function validatorVotersLength(address _val) public view returns (uint256) { 1351 return validatorToVoters[_val].length(); 1352 } 1353 1354 /** 1355 * @dev return validator info 1356 */ 1357 function validators(address _val) external view returns (Validator memory) { 1358 return _validators[_val]; 1359 } 1360 1361 /** 1362 * @dev batch query validator info 1363 */ 1364 function batchValidators(address[] memory _vals) 1365 external 1366 view 1367 returns (Validator[] memory) 1368 { 1369 uint256 len = _vals.length; 1370 Validator[] memory valInfos = new Validator[](len); 1371 1372 for (uint256 i = 0; i < len; i++) { 1373 valInfos[i] = _validators[_vals[i]]; 1374 } 1375 return valInfos; 1376 } 1377 1378 /** 1379 * @dev return curEpochValidators 1380 */ 1381 function getCurEpochValidators() external view returns (address[] memory) { 1382 return curEpochValidators; 1383 } 1384 1385 /** 1386 * @dev True: effictive 1387 */ 1388 function isEffictiveValidator(address addr) external view returns (bool) { 1389 return _validators[addr].status == ValidatorStatus.effictive; 1390 } 1391 1392 /** 1393 * @dev return effictive Validators count 1394 */ 1395 function effictiveValsLength() public view returns (uint256) { 1396 return effictiveValidators.length(); 1397 } 1398 1399 /** 1400 * @dev return all effictive Validators 1401 */ 1402 function getEffictiveValidators() public view returns (address[] memory) { 1403 uint256 len = effictiveValidators.length(); 1404 address[] memory vals = new address[](len); 1405 1406 for (uint256 i = 0; i < len; i++) { 1407 vals[i] = effictiveValidators.at(i); 1408 } 1409 return vals; 1410 } 1411 1412 function getEffictiveValidatorsWithPage(uint256 page, uint256 size) 1413 public 1414 view 1415 returns (address[] memory) 1416 { 1417 require(page > 0 && size > 0, "Validators: Requests param error"); 1418 uint256 len = effictiveValidators.length(); 1419 uint256 start = (page - 1) * size; 1420 if (len < start) { 1421 size = 0; 1422 } else { 1423 uint256 length = len - start; 1424 if (length < size) { 1425 size = length; 1426 } 1427 } 1428 1429 address[] memory vals = new address[](size); 1430 for (uint256 i = 0; i < size; i++) { 1431 vals[i] = effictiveValidators.at(i + start); 1432 } 1433 return vals; 1434 } 1435 1436 /** 1437 * @dev return invalid Validators count 1438 */ 1439 function invalidValsLength() public view returns (uint256) { 1440 return invalidValidators.length(); 1441 } 1442 1443 /** 1444 * @dev return all invalid Validators 1445 */ 1446 function getInvalidValidators() public view returns (address[] memory) { 1447 uint256 len = invalidValidators.length(); 1448 address[] memory vals = new address[](len); 1449 1450 for (uint256 i = 0; i < len; i++) { 1451 vals[i] = invalidValidators.at(i); 1452 } 1453 return vals; 1454 } 1455 1456 function getInvalidValidatorsWithPage(uint256 page, uint256 size) 1457 public 1458 view 1459 returns (address[] memory) 1460 { 1461 require(page > 0 && size > 0, "Validators: Requests param error"); 1462 uint256 len = invalidValidators.length(); 1463 uint256 start = (page - 1) * size; 1464 if (len < start) { 1465 size = 0; 1466 } else { 1467 uint256 length = len - start; 1468 if (length < size) { 1469 size = length; 1470 } 1471 } 1472 1473 address[] memory vals = new address[](size); 1474 for (uint256 i = 0; i < size; i++) { 1475 vals[i] = invalidValidators.at(i + start); 1476 } 1477 return vals; 1478 } 1479 1480 /** 1481 * @dev return canceling validators count 1482 */ 1483 function CancelQueueValidatorsLength() public view returns (uint256) { 1484 return cancelingValidators.length(); 1485 } 1486 1487 /** 1488 * @dev return Cancel Queue Validators 1489 */ 1490 function getCancelQueueValidators() public view returns (address[] memory) { 1491 uint256 len = cancelingValidators.length(); 1492 address[] memory vals = new address[](len); 1493 1494 for (uint256 i = 0; i < len; i++) { 1495 vals[i] = cancelingValidators.at(i); 1496 } 1497 return vals; 1498 } 1499 1500 /** 1501 * @dev update validator deposit 1502 */ 1503 function updateValidatorDeposit(uint256 _deposit) 1504 external 1505 payable 1506 nonReentrant 1507 { 1508 Validator storage val = _validators[msg.sender]; 1509 require( 1510 val.status == ValidatorStatus.effictive, 1511 "Validators: illegal msg.sender" 1512 ); 1513 if (_deposit >= val.deposit) { 1514 require( 1515 msg.value >= _deposit - val.deposit, 1516 "Validators: illegal deposit" 1517 ); 1518 uint256 sub = _deposit - val.deposit; 1519 totalDeposit += sub; 1520 val.deposit = _deposit; 1521 payable(msg.sender).transfer(msg.value - sub); 1522 } else { 1523 require(_deposit >= MIN_DEPOSIT, "Validators: illegal deposit"); 1524 uint256 sub = val.deposit - _deposit; 1525 payable(msg.sender).transfer(sub); 1526 val.deposit = _deposit; 1527 totalDeposit -= sub; 1528 } 1529 1530 emit LogUpdateValidatorDeposit(msg.sender, val.deposit); 1531 } 1532 1533 /** 1534 * @dev update validator rate 1535 */ 1536 function updateValidatorRate(uint8 _rate) external nonReentrant { 1537 Validator storage val = _validators[msg.sender]; 1538 require( 1539 val.status == ValidatorStatus.effictive, 1540 "Validators: illegal msg.sender" 1541 ); 1542 require( 1543 val.rateSettLockingEndBlock < block.number, 1544 "Validators: illegal rate set block" 1545 ); 1546 require( 1547 _rate >= MIN_RATE && val.rate <= MAX_RATE, 1548 "Validators: illegal Allocation ratio" 1549 ); 1550 uint8 preRate = val.rate; 1551 val.rate = _rate; 1552 val.rateSettLockingEndBlock = 1553 block.number + 1554 RATE_SET_LOCK_EPOCHS * 1555 EPOCH_BLOCKS; 1556 1557 emit LogUpdateValidatorRate(msg.sender, preRate, _rate); 1558 } 1559 1560 /** 1561 * @dev update validator name and details 1562 */ 1563 function updateValidatorNameDetails( 1564 string memory _name, 1565 string memory _details 1566 ) external nonReentrant { 1567 Validator storage val = _validators[msg.sender]; 1568 require( 1569 bytes(_details).length <= MAX_VALIDATOR_DETAIL_LENGTH, 1570 "Validators: Details is too long" 1571 ); 1572 require( 1573 bytes(_name).length <= MAX_VALIDATOR_NAME_LENGTH, 1574 "Validators: name is too long" 1575 ); 1576 val.name = _name; 1577 val.details = _details; 1578 } 1579 1580 function addValidatorFromProposal( 1581 address _val, 1582 uint256 _deposit, 1583 uint8 _rate, 1584 string memory _name, 1585 string memory _details 1586 ) external payable onlyProposalsC { 1587 require(!_val.isContract(), "Validators: validator address error"); 1588 require( 1589 msg.value == _deposit, 1590 "Validators: deposit not equal msg.value" 1591 ); 1592 1593 Validator storage val = _validators[_val]; 1594 require( 1595 val.status == ValidatorStatus.canceled, 1596 "Validators: validator status error" 1597 ); 1598 1599 val.status = ValidatorStatus.effictive; 1600 val.deposit = _deposit; 1601 val.rate = _rate; 1602 val.name = _name; 1603 val.details = _details; 1604 1605 effictiveValidators.add(_val); 1606 invalidValidators.remove(_val); 1607 totalDeposit += _deposit; 1608 1609 emit LogAddValidator(_val, _deposit, _rate); 1610 } 1611 1612 function kickoutValidator(address _val) external onlySysRewardsC { 1613 Validator storage val = _validators[_val]; 1614 require( 1615 val.status == ValidatorStatus.effictive || 1616 val.status == ValidatorStatus.kickout, 1617 "Validators: validator status error" 1618 ); 1619 val.status = ValidatorStatus.kickout; 1620 if (effictiveValidators.contains(_val)) { 1621 effictiveValidators.remove(_val); 1622 invalidValidators.add(_val); 1623 totalDeposit -= val.deposit; 1624 } 1625 } 1626 1627 /** 1628 * @dev restore validator from kickout status 1629 */ 1630 function restore() external nonReentrant { 1631 require( 1632 effictiveValidators.length() < MAX_VALIDATORS_COUNT, 1633 "Validators: length of the validator must be less than MAX_VALIDATORS_COUNT" 1634 ); 1635 Validator storage val = _validators[msg.sender]; 1636 require( 1637 !cancelingValidators.contains(msg.sender), 1638 "Validators: this validator is canceling" 1639 ); 1640 require( 1641 val.status == ValidatorStatus.kickout, 1642 "Validators: validator must be kickout" 1643 ); 1644 val.status = ValidatorStatus.effictive; 1645 effictiveValidators.add(msg.sender); 1646 invalidValidators.remove(msg.sender); 1647 totalDeposit += val.deposit; 1648 1649 emit LogRestoreValidator(msg.sender); 1650 } 1651 1652 function unstake() external nonReentrant { 1653 Validator storage val = _validators[msg.sender]; 1654 require( 1655 val.status == ValidatorStatus.effictive || 1656 val.status == ValidatorStatus.kickout, 1657 "Validators: illegal msg.sender" 1658 ); 1659 if (curEpochValidatorsIdMap[msg.sender] == 0) { 1660 cancelingValidators.remove(msg.sender); 1661 val.status = ValidatorStatus.canceling; 1662 val.unstakeLockingEndBlock = 1663 block.number + 1664 VALIDATOR_UNSTAKE_LOCK_EPOCHS * 1665 EPOCH_BLOCKS; 1666 1667 if (effictiveValidators.contains(msg.sender)) { 1668 effictiveValidators.remove(msg.sender); 1669 invalidValidators.add(msg.sender); 1670 totalDeposit -= val.deposit; 1671 } 1672 } else { 1673 val.status = ValidatorStatus.cancelQueue; 1674 cancelingValidators.add(msg.sender); 1675 } 1676 emit LogUnstakeValidator(msg.sender); 1677 } 1678 1679 function _cancelValidatorWhileElect() internal { 1680 for (uint256 i = 0; i < cancelingValidators.length(); i++) { 1681 address _val = cancelingValidators.at(0); 1682 1683 Validator storage val = _validators[_val]; 1684 val.status = ValidatorStatus.canceling; 1685 val.unstakeLockingEndBlock = 1686 block.number + 1687 VALIDATOR_UNSTAKE_LOCK_EPOCHS * 1688 EPOCH_BLOCKS; 1689 1690 cancelingValidators.remove(_val); 1691 1692 if (effictiveValidators.contains(_val)) { 1693 effictiveValidators.remove(_val); 1694 invalidValidators.add(_val); 1695 totalDeposit -= val.deposit; 1696 } 1697 } 1698 } 1699 1700 function redeem() external nonReentrant { 1701 Validator storage val = _validators[msg.sender]; 1702 require( 1703 val.unstakeLockingEndBlock < block.number, 1704 "Validators: illegal redeem block" 1705 ); 1706 require( 1707 val.status == ValidatorStatus.canceling && 1708 curEpochValidatorsIdMap[msg.sender] == 0, 1709 "Validators: illegal msg.sender" 1710 ); 1711 1712 val.status = ValidatorStatus.canceled; 1713 payable(msg.sender).transfer(val.deposit); 1714 val.deposit = 0; 1715 val.unstakeLockingEndBlock = 0; 1716 val.rateSettLockingEndBlock = 0; 1717 invalidValidators.remove(msg.sender); 1718 1719 emit LogRedeemValidator(msg.sender); 1720 } 1721 1722 function voteValidator( 1723 address _voter, 1724 address _val, 1725 uint256 _votes 1726 ) external payable onlyNodeVoteC { 1727 _validators[_val].votes += _votes; 1728 validatorToVoters[_val].add(_voter); 1729 } 1730 1731 function cancelVoteValidator( 1732 address _voter, 1733 address _val, 1734 uint256 _votes, 1735 bool _clear 1736 ) external onlyNodeVoteC { 1737 _validators[_val].votes -= _votes; 1738 if (_clear) { 1739 validatorToVoters[_val].remove(_voter); 1740 } 1741 } 1742 1743 function tryElect() external onlySysRewardsC { 1744 _cancelValidatorWhileElect(); 1745 1746 uint256 nextEpochValCount = nextEpochValidatorCount(); 1747 uint256 effictiveLen = effictiveValidators.length(); 1748 1749 for (uint256 i = 0; i < curEpochValidators.length; i++) { 1750 address _val = curEpochValidators[i]; 1751 sysRewards.updateValidatorWhileEpochEnd( 1752 _val, 1753 _validators[_val].votes 1754 ); 1755 delete curEpochValidatorsIdMap[_val]; 1756 } 1757 delete curEpochValidators; 1758 1759 uint256 total = 0; 1760 for (uint256 i = 0; i < effictiveLen; i++) { 1761 address val = effictiveValidators.at(i); 1762 total += _validators[val].votes + _validators[val].deposit; 1763 } 1764 1765 uint256 totalTemp = total; 1766 uint256 nextEpoch = currentEpoch() + 1; 1767 1768 if (nextEpochValCount >= effictiveLen) { 1769 for (uint256 i = 0; i < effictiveLen; i++) { 1770 address val = effictiveValidators.at(i); 1771 curEpochValidators.push(val); 1772 curEpochValidatorsIdMap[val] = curEpochValidators.length; 1773 sysRewards.updateValidatorWhileElect( 1774 val, 1775 _validators[val].rate, 1776 nextEpoch 1777 ); 1778 } 1779 } else { 1780 // for-loop tryElect 1781 for (uint256 i = 0; i < nextEpochValCount; i++) { 1782 if (total <= 0) break; 1783 // get random number 1784 uint256 randDeposit = rand(total, i); 1785 1786 for (uint256 j = 0; j < effictiveLen; j++) { 1787 address val = effictiveValidators.at(j); 1788 if (curEpochValidatorsIdMap[val] != 0) continue; 1789 uint256 deposit = _validators[val].votes + 1790 _validators[val].deposit; 1791 if (randDeposit <= deposit) { 1792 curEpochValidators.push(val); 1793 curEpochValidatorsIdMap[val] = curEpochValidators 1794 .length; 1795 total -= deposit; 1796 sysRewards.updateValidatorWhileElect( 1797 val, 1798 _validators[val].rate, 1799 nextEpoch 1800 ); 1801 break; 1802 } 1803 randDeposit -= deposit; 1804 } 1805 } 1806 } 1807 1808 sysRewards.updateEpochWhileElect( 1809 totalTemp, 1810 curEpochValidators.length, 1811 effictiveLen, 1812 nextEpoch 1813 ); 1814 } 1815 1816 function rand(uint256 _length, uint256 _i) internal view returns (uint256) { 1817 uint256 random = uint256( 1818 keccak256(abi.encodePacked(blockhash(block.number - _i - 1), _i)) 1819 ); 1820 return random % _length; 1821 } 1822 1823 function recentFourteenEpochAvgValCount() internal view returns (uint256) { 1824 uint256 curEpoch = currentEpoch(); 1825 if (curEpoch == 0) { 1826 return effictiveValidators.length(); 1827 } 1828 uint256 sumValidatorCount = 0; 1829 uint256 avg = 14; 1830 if (curEpoch < avg - 1) { 1831 avg = curEpoch; 1832 } 1833 for (uint256 i = 0; i < avg; i++) { 1834 (, , , uint256 effValCount) = sysRewards.epochs(curEpoch - i); 1835 sumValidatorCount += effValCount; 1836 } 1837 return sumValidatorCount / avg; 1838 } 1839 1840 function nextEpochValidatorCount() internal view returns (uint256) { 1841 uint256 avgCount = recentFourteenEpochAvgValCount(); 1842 if (avgCount < MIN_LEVEL_VALIDATOR_COUNT) { 1843 return MAX_VALIDATOR_COUNT_LV1; 1844 } 1845 if (avgCount < MEDIUM_LEVEL_VALIDATOR_COUNT) { 1846 return MAX_VALIDATOR_COUNT_LV2; 1847 } 1848 if (avgCount < MAX_LEVEL_VALIDATOR_COUNT) { 1849 return MAX_VALIDATOR_COUNT_LV3; 1850 } 1851 // avgCount >= MAX_LEVEL_VALIDATOR_COUNT 1852 return MAX_VALIDATOR_COUNT_LV4; 1853 } 1854 1855 } 1856 1857 interface IValidators { 1858 function isEffictiveValidator(address addr) external view returns (bool); 1859 1860 function getEffictiveValidators() external view returns (address[] memory); 1861 1862 function getInvalidValidators() external view returns (address[] memory); 1863 1864 function effictiveValsLength() external view returns (uint256); 1865 1866 function invalidValsLength() external view returns (uint256); 1867 1868 function validators(address _val) 1869 external 1870 view 1871 returns (Validators.Validator calldata); 1872 1873 function kickoutValidator(address _val) external; 1874 1875 function tryElect() external; 1876 1877 function addValidatorFromProposal( 1878 address _addr, 1879 uint256 _deposit, 1880 uint8 _rate, 1881 string memory _name, 1882 string memory _details 1883 ) external payable; 1884 1885 function voteValidator( 1886 address _voter, 1887 address _val, 1888 uint256 _votes 1889 ) external payable; 1890 1891 function cancelVoteValidator( 1892 address _voter, 1893 address _val, 1894 uint256 _votes, 1895 bool _clear 1896 ) external payable; 1897 1898 } 1899 1900 contract SystemRewards is Base, Initializable, ReentrancyGuard { 1901 using EnumerableSet for EnumerableSet.UintSet; 1902 using EnumerableSet for EnumerableSet.AddressSet; 1903 1904 struct Reward { 1905 uint256 validatorReward; 1906 uint256 delegatorsReward; 1907 uint8 rate; 1908 } 1909 1910 struct SysRewards { 1911 /// @notice pending epochs with block reward 1912 EnumerableSet.UintSet epochs; 1913 /// @notice epoch => Reward 1914 mapping(uint256 => Reward) rewards; 1915 /// @notice penging validator reward . non real-time 1916 uint256 pendingReward; 1917 /// @notice reward per vote for delegates 1918 uint256 rewardPerVote; 1919 } 1920 1921 struct SysRewardsInfo { 1922 uint256[] epochs; 1923 uint256[] validatorRewards; 1924 uint256[] delegatorsRewards; 1925 uint8[] rates; 1926 uint256 pendingReward; 1927 uint256 frozenReward; 1928 uint256 rewardPerVote; 1929 } 1930 1931 mapping(address => SysRewards) sysRewards; 1932 1933 struct Epoch { 1934 uint256 blockReward; 1935 uint256 tvl; 1936 uint256 validatorCount; 1937 uint256 effictiveValCount; 1938 address[] kickoutValidators; 1939 } 1940 1941 /// @notice epoch => Epoch 1942 mapping(uint256 => Epoch) public epochs; 1943 1944 IValidators public validatorC; 1945 1946 INodeVote public nodeVoteC; 1947 1948 struct Punish { 1949 uint256 count; 1950 uint256[] punishBlocks; 1951 uint256[] kickoutBlocks; 1952 uint256[] burnRewards; 1953 } 1954 1955 /// @notice validator => epoch => Punish 1956 mapping(address => mapping(uint256 => Punish)) _punishInfo; 1957 1958 /// @notice validator => block => [_valReward, _delegatorReward] 1959 mapping(address => mapping(uint256 => uint256[])) _distributeBlockRewardLog; 1960 1961 event LogEarnValidatorReward(address indexed _val, uint256 _amount); 1962 1963 modifier onlyValidatorC() { 1964 require( 1965 msg.sender == address(validatorC), 1966 "SystemRewards: not Validator contract" 1967 ); 1968 _; 1969 } 1970 1971 function initialize(address _validator, address _node) 1972 public 1973 onlySystem 1974 initializer 1975 { 1976 validatorC = IValidators(_validator); 1977 nodeVoteC = INodeVote(_node); 1978 } 1979 1980 function kickoutInfo(uint256 _epoch) 1981 public 1982 view 1983 returns (address[] memory) 1984 { 1985 return epochs[_epoch].kickoutValidators; 1986 } 1987 1988 function punishInfo(address _val, uint256 _epoch) 1989 public 1990 view 1991 returns (Punish memory) 1992 { 1993 return _punishInfo[_val][_epoch]; 1994 } 1995 1996 function distributeBlockRewardInfo(address _val, uint256 _block) 1997 public 1998 view 1999 returns (uint256[] memory) 2000 { 2001 return _distributeBlockRewardLog[_val][_block]; 2002 } 2003 2004 /** 2005 * @dev return rewardPerVote of validator 2006 */ 2007 function getRewardPerVote(address _val) public view returns (uint256) { 2008 return sysRewards[_val].rewardPerVote; 2009 } 2010 2011 function validatorEpochRewardInfo(address _val, uint256 _epoch) 2012 public 2013 view 2014 returns (Reward memory) 2015 { 2016 return sysRewards[_val].rewards[_epoch]; 2017 } 2018 2019 function validatorRewardsInfo(address _val) 2020 public 2021 view 2022 returns (SysRewardsInfo memory) 2023 { 2024 SysRewards storage sysReward = sysRewards[_val]; 2025 (uint256 len, uint256 curEpoch) = ( 2026 sysReward.epochs.length(), 2027 currentEpoch() 2028 ); 2029 (uint256 avaliable, uint256 frozen) = (sysReward.pendingReward, 0); 2030 2031 uint256[] memory _epochs = new uint256[](len); 2032 uint256[] memory validatorRewards = new uint256[](len); 2033 uint256[] memory delegatorsRewards = new uint256[](len); 2034 uint8[] memory rates = new uint8[](len); 2035 2036 for (uint256 i = 0; i < len; i++) { 2037 uint256 epoch = sysReward.epochs.at(i); 2038 _epochs[i] = epoch; 2039 validatorRewards[i] = sysReward.rewards[epoch].validatorReward; 2040 delegatorsRewards[i] = sysReward.rewards[epoch].delegatorsReward; 2041 rates[i] = sysReward.rewards[epoch].rate; 2042 if (epoch + VALIDATOR_REWARD_LOCK_EPOCHS < curEpoch) { 2043 avaliable += sysReward.rewards[epoch].validatorReward; 2044 } else { 2045 frozen += sysReward.rewards[epoch].validatorReward; 2046 } 2047 } 2048 SysRewardsInfo memory info; 2049 info.epochs = _epochs; 2050 info.validatorRewards = validatorRewards; 2051 info.delegatorsRewards = delegatorsRewards; 2052 info.rates = rates; 2053 info.pendingReward = avaliable; 2054 info.frozenReward = frozen; 2055 info.rewardPerVote = sysReward.rewardPerVote; 2056 2057 return info; 2058 } 2059 2060 function pendingValidatorReward(address _val) 2061 public 2062 view 2063 returns (uint256, uint256) 2064 { 2065 SysRewards storage sysReward = sysRewards[_val]; 2066 (uint256 len, uint256 curEpoch) = ( 2067 sysReward.epochs.length(), 2068 currentEpoch() 2069 ); 2070 2071 (uint256 avaliable, uint256 frozen) = (sysReward.pendingReward, 0); 2072 2073 for (uint256 i = 0; i < len; i++) { 2074 uint256 epoch = sysReward.epochs.at(i); 2075 if (epoch + VALIDATOR_REWARD_LOCK_EPOCHS < curEpoch) { 2076 avaliable += sysReward.rewards[epoch].validatorReward; 2077 } else { 2078 frozen += sysReward.rewards[epoch].validatorReward; 2079 } 2080 } 2081 return (avaliable, frozen); 2082 } 2083 2084 /** 2085 * @dev earn validator reward 2086 */ 2087 function earnValidatorReward() external nonReentrant { 2088 SysRewards storage sysReward = sysRewards[msg.sender]; 2089 uint256 pendingReward = _updateValidatorPendingReward( 2090 msg.sender, 2091 false 2092 ); 2093 payable(msg.sender).transfer(pendingReward); 2094 sysReward.pendingReward = 0; 2095 emit LogEarnValidatorReward(msg.sender, pendingReward); 2096 } 2097 2098 /** 2099 * @dev earn validator reward from Validator contract 2100 */ 2101 function earnValRewardFromValidatorC(address _val) external onlyValidatorC { 2102 SysRewards storage sysReward = sysRewards[_val]; 2103 uint256 pendingReward = _updateValidatorPendingReward(_val, false); 2104 if (pendingReward == 0) { 2105 emit LogEarnValidatorReward(_val, pendingReward); 2106 return; 2107 } 2108 payable(_val).transfer(pendingReward); 2109 sysReward.pendingReward = 0; 2110 emit LogEarnValidatorReward(_val, pendingReward); 2111 } 2112 2113 function distributeBlockReward(uint256 _reward) 2114 external 2115 payable 2116 onlyMiner 2117 onlySystem 2118 nonReentrant 2119 { 2120 SysRewards storage sysReward = sysRewards[msg.sender]; 2121 uint256 curEpoch = currentEpoch(); 2122 2123 uint8 rate = sysReward.rewards[curEpoch].rate; 2124 2125 // calculate block reward 2126 uint256 delegatorsReward = (_reward * uint256(rate)) / 2127 uint256(MAX_RATE); 2128 uint256 valReward = _reward - delegatorsReward; 2129 2130 // distribute block reward 2131 sysReward.rewards[curEpoch].validatorReward += valReward; 2132 sysReward.rewards[curEpoch].delegatorsReward += delegatorsReward; 2133 2134 _distributeBlockRewardLog[msg.sender][block.number].push(valReward); 2135 _distributeBlockRewardLog[msg.sender][block.number].push( 2136 delegatorsReward 2137 ); 2138 2139 // The previous block when the epoch is updated 2140 if (block.number % EPOCH_BLOCKS == EPOCH_BLOCKS - 1) { 2141 // tryElect 2142 validatorC.tryElect(); 2143 } 2144 } 2145 2146 function punish(address _val) external onlyMiner onlySystem returns (bool) { 2147 SysRewards storage sysReward = sysRewards[_val]; 2148 uint256 curEpoch = currentEpoch(); 2149 Punish storage _punish = _punishInfo[_val][curEpoch]; 2150 2151 _punish.count += 1; 2152 _punish.punishBlocks.push(block.number); 2153 2154 if ( 2155 _punish.count >= MAX_PUNISH_COUNT && 2156 _punish.count % MAX_PUNISH_COUNT == 0 2157 ) { 2158 uint256 curEpochValReward = sysReward 2159 .rewards[curEpoch] 2160 .validatorReward; 2161 sysReward.rewards[curEpoch].validatorReward = 0; 2162 _punish.kickoutBlocks.push(block.number); 2163 _punish.burnRewards.push(curEpochValReward); 2164 payable(BLACK_HOLE_ADDRESS).transfer(curEpochValReward); 2165 2166 bool hasKickout = isValidatorKickout( 2167 epochs[curEpoch].kickoutValidators, 2168 _val 2169 ); 2170 if (!hasKickout) { 2171 epochs[curEpoch].kickoutValidators.push(_val); 2172 validatorC.kickoutValidator(_val); 2173 } 2174 2175 return true; 2176 } 2177 return false; 2178 } 2179 2180 /** 2181 * @dev update reward epochs and rate while tryElect 2182 */ 2183 function updateValidatorWhileElect( 2184 address _val, 2185 uint8 _rate, 2186 uint256 _newEpoch 2187 ) external onlyValidatorC { 2188 SysRewards storage sysReward = sysRewards[_val]; 2189 sysReward.epochs.add(_newEpoch); 2190 sysReward.rewards[_newEpoch].rate = _rate; 2191 } 2192 2193 /** 2194 * @dev update epoch info while tryElect 2195 */ 2196 function updateEpochWhileElect( 2197 uint256 _tvl, 2198 uint256 _valCount, 2199 uint256 _effictiveValCount, 2200 uint256 _newEpoch 2201 ) external onlyValidatorC { 2202 epochs[_newEpoch].tvl = _tvl; 2203 epochs[_newEpoch].validatorCount = _valCount; 2204 epochs[_newEpoch].effictiveValCount = _effictiveValCount; 2205 _calculateBlockReward(_newEpoch); 2206 } 2207 2208 /** 2209 * @dev update validator rewardPerVote and pendingReward while epoch ending 2210 */ 2211 function updateValidatorWhileEpochEnd(address _val, uint256 _votes) 2212 external 2213 onlyValidatorC 2214 { 2215 _updateValidatorPendingReward(_val, true); 2216 2217 SysRewards storage sysReward = sysRewards[_val]; 2218 uint256 curEpoch = currentEpoch(); 2219 if (_votes > 0) { 2220 sysReward.rewardPerVote += 2221 (sysReward.rewards[curEpoch].delegatorsReward * 2222 SAFE_MULTIPLIER) / 2223 _votes; 2224 payable(address(nodeVoteC)).transfer( 2225 sysReward.rewards[curEpoch].delegatorsReward 2226 ); 2227 } else { 2228 payable(BLACK_HOLE_ADDRESS).transfer( 2229 sysReward.rewards[curEpoch].delegatorsReward 2230 ); 2231 } 2232 } 2233 2234 /** 2235 * @dev update validator pendingReward while epoch ending 2236 */ 2237 function _updateValidatorPendingReward(address _val, bool _isEpochEnd) 2238 internal 2239 returns (uint256) 2240 { 2241 SysRewards storage sysReward = sysRewards[_val]; 2242 (uint256 len, uint256 curEpoch) = ( 2243 sysReward.epochs.length(), 2244 currentEpoch() 2245 ); 2246 2247 uint256[] memory _epochs = new uint256[](len); 2248 for (uint256 i = 0; i < len; i++) { 2249 _epochs[i] = sysReward.epochs.at(i); 2250 } 2251 2252 for (uint256 i = 0; i < len; i++) { 2253 uint256 epoch = _epochs[i]; 2254 if ( 2255 epoch + VALIDATOR_REWARD_LOCK_EPOCHS < curEpoch || 2256 (_isEpochEnd == true && 2257 epoch + VALIDATOR_REWARD_LOCK_EPOCHS <= curEpoch) 2258 ) { 2259 sysReward.pendingReward += sysReward 2260 .rewards[epoch] 2261 .validatorReward; 2262 sysReward.epochs.remove(epoch); 2263 } 2264 } 2265 return sysReward.pendingReward; 2266 } 2267 2268 /** 2269 * @dev calculate epoch's BlockReward while tryElect 2270 */ 2271 function _calculateBlockReward(uint256 _newEpoch) internal { 2272 (uint256 sum, uint256 count) = (0, 0); 2273 2274 if (_newEpoch == 0) { 2275 sum = epochs[_newEpoch].tvl; 2276 count = 1; 2277 } else { 2278 count = _newEpoch >= 14 ? 14 : _newEpoch; 2279 for (uint256 i = _newEpoch - count; i < _newEpoch; i++) { 2280 sum += epochs[i].tvl; 2281 } 2282 } 2283 2284 uint256 avg = sum / count; 2285 if (avg < TOTAL_DEPOSIT_LV1) { 2286 epochs[_newEpoch].blockReward = REWARD_DEPOSIT_UNDER_LV1; 2287 } else if (TOTAL_DEPOSIT_LV1 <= avg && avg < TOTAL_DEPOSIT_LV2) { 2288 epochs[_newEpoch].blockReward = REWARD_DEPOSIT_FROM_LV1_TO_LV2; 2289 } else if (TOTAL_DEPOSIT_LV2 <= avg && avg < TOTAL_DEPOSIT_LV3) { 2290 epochs[_newEpoch].blockReward = REWARD_DEPOSIT_FROM_LV2_TO_LV3; 2291 } else if (TOTAL_DEPOSIT_LV3 <= avg && avg < TOTAL_DEPOSIT_LV4) { 2292 epochs[_newEpoch].blockReward = REWARD_DEPOSIT_FROM_LV3_TO_LV4; 2293 } else if (TOTAL_DEPOSIT_LV4 <= avg && avg < TOTAL_DEPOSIT_LV5) { 2294 epochs[_newEpoch].blockReward = REWARD_DEPOSIT_FROM_LV4_TO_LV5; 2295 } else { 2296 epochs[_newEpoch].blockReward = REWARD_DEPOSIT_OVER_LV5; 2297 } 2298 } 2299 2300 function isValidatorKickout(address[] memory kkvals, address val) 2301 internal 2302 pure 2303 returns (bool) 2304 { 2305 for (uint256 i = 0; i < kkvals.length; i++) { 2306 if (kkvals[i] == val) { 2307 return true; 2308 } 2309 } 2310 return false; 2311 } 2312 2313 }