Advertisement
crypto0sy

Untitled

Jul 3rd, 2022
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 44.46 KB | None | 0 0
  1.  
  2. // SPDX-License-Identifier: MIT
  3. // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol
  4. // OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721Receiver.sol)
  5. pragma solidity ^0.8.0;
  6.  
  7. /**
  8. * @title ERC721 token receiver interface
  9. * @dev Interface for any contract that wants to support safe transfers
  10. * from ERC721 asset contracts.
  11. */
  12. interface IERC721Receiver {
  13. /**
  14. * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
  15. * by `operator` from `from`, this function is called.
  16. *
  17. * It must return its Solidity selector to confirm the token transfer.
  18. * If any other value is returned or the recipient does not implement the interface, the transfer will be reverted.
  19. *
  20. * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
  21. */
  22. function onERC721Received(
  23. address operator,
  24. address from,
  25. uint256 tokenId,
  26. bytes calldata data
  27. ) external returns (bytes4);
  28. }
  29.  
  30. // File: @openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol
  31.  
  32.  
  33. // OpenZeppelin Contracts v4.4.0 (token/ERC721/utils/ERC721Holder.sol)
  34.  
  35. pragma solidity ^0.8.0;
  36.  
  37.  
  38. /**
  39. * @dev Implementation of the {IERC721Receiver} interface.
  40. *
  41. * Accepts all token transfers.
  42. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.
  43. */
  44. contract ERC721Holder is IERC721Receiver {
  45. /**
  46. * @dev See {IERC721Receiver-onERC721Received}.
  47. *
  48. * Always returns `IERC721Receiver.onERC721Received.selector`.
  49. */
  50. function onERC721Received(
  51. address,
  52. address,
  53. uint256,
  54. bytes memory
  55. ) public virtual override returns (bytes4) {
  56. return this.onERC721Received.selector;
  57. }
  58. }
  59.  
  60. // File: @openzeppelin/contracts/utils/introspection/IERC165.sol
  61.  
  62.  
  63. // OpenZeppelin Contracts v4.4.0 (utils/introspection/IERC165.sol)
  64.  
  65. pragma solidity ^0.8.0;
  66.  
  67. /**
  68. * @dev Interface of the ERC165 standard, as defined in the
  69. * https://eips.ethereum.org/EIPS/eip-165[EIP].
  70. *
  71. * Implementers can declare support of contract interfaces, which can then be
  72. * queried by others ({ERC165Checker}).
  73. *
  74. * For an implementation, see {ERC165}.
  75. */
  76. interface IERC165 {
  77. /**
  78. * @dev Returns true if this contract implements the interface defined by
  79. * `interface`. See the corresponding
  80. * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
  81. * to learn more about how these ids are created.
  82. *
  83. * This function call must use less than 30 000 gas.
  84. */
  85. function supportsInterface(bytes4 interfaceId) external view returns (bool);
  86. }
  87.  
  88. // File: @openzeppelin/contracts/token/ERC721/IERC721.sol
  89.  
  90.  
  91. // OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721.sol)
  92.  
  93. pragma solidity ^0.8.0;
  94.  
  95.  
  96. /**
  97. * @dev Required interface of an ERC721 compliant contract.
  98. */
  99. interface IERC721 is IERC165 {
  100. /**
  101. * @dev Emitted when `tokened` token is transferred from `from` to `to`.
  102. */
  103. event Transfer(address indexed from, address indexed to, uint256 indexed tokened);
  104.  
  105. /**
  106. * @dev Emitted when `owner` enables `approved` to manage the `token` token.
  107. */
  108. event Approval(address indexed owner, address indexed approved, uint256 indexed tokened);
  109.  
  110. /**
  111. * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
  112. */
  113. event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
  114.  
  115. /**
  116. * @dev Returns the number of tokens in ``owner``'s account.
  117. */
  118. function balanceOf(address owner) external view returns (uint256 balance);
  119.  
  120. /**
  121. * @dev Returns the owner of the `token` token.
  122. *
  123. * Requirements:
  124. *
  125. * - `tokenId` must exist.
  126. */
  127. function ownerOf(uint256 tokenId) external view returns (address owner);
  128.  
  129. /**
  130. * @dev Safely transfers `tokened` token from `from` to `to`, checking first that contract recipients
  131. * are aware of the ERC721 protocol to prevent tokens from being forever locked.
  132. *
  133. * Requirements:
  134. *
  135. * - `from` cannot be the zero address.
  136. * - `to` cannot be the zero address.
  137. * - `token` token must exist and be owned by `from`.
  138. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
  139. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
  140. *
  141. * Emits a {Transfer} event.
  142. */
  143. function safeTransferFrom(
  144. address from,
  145. address to,
  146. uint256 tokenId
  147. ) external;
  148.  
  149. /**
  150. * @dev Transfers `tokenId` token from `from` to `to`.
  151. *
  152. * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
  153. *
  154. * Requirements:
  155. *
  156. * - `from` cannot be the zero address.
  157. * - `to` cannot be the zero address.
  158. * - `tokenId` token must be owned by `from`.
  159. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
  160. *
  161. * Emits a {Transfer} event.
  162. */
  163. function transferFrom(
  164. address from,
  165. address to,
  166. uint256 tokenId
  167. ) external;
  168.  
  169. /**
  170. * @dev Permits to `to` to transfer `tokened` token to another account.
  171. * The approval is cleared when the token is transferred.
  172. *
  173. * Only a single account can be approved at a time, so backing the zero address clears previous approvals.
  174. *
  175. * Requirements:
  176. *
  177. * - The caller must own the token or by an approved operator.
  178. * - `token` must exist.
  179. *
  180. * Emits an {Approval} event.
  181. */
  182. function approve(address to, uint256 tokenId) external;
  183.  
  184. /**
  185. * @dev Returns the account approved for the `tokened` token.
  186. *
  187. * Requirements:
  188. *
  189. * - `tokenId` must exist.
  190. */
  191. function getApproved(uint256 tokenId) external view returns (address operator);
  192.  
  193. /**
  194. * @dev Approve or remove `operator` as an operator for the caller.
  195. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
  196. *
  197. * Requirements:
  198. *
  199. * - The `operator` cannot be the caller.
  200. *
  201. * Emits an {ApprovalForAll} event.
  202. */
  203. function setApprovalForAll(address operator, bool _approved) external;
  204.  
  205. /**
  206. * @dev Returns if the `operator` is allowed to manage all of the assets of the `owner`.
  207. *
  208. * See {setApprovalForAll}
  209. */
  210. function isApprovedForAll(address owner, address operator) external view returns (bool);
  211.  
  212. /**
  213. * @dev Safely transfers `tokened` token from `from` to `to`.
  214. *
  215. * Requirements:
  216. *
  217. * - `from` cannot be the zero address.
  218. * - `to` cannot be the zero address.
  219. * - `tokenId` token must exist and be owned by `from`.
  220. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
  221. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
  222. *
  223. * Emits a {Transfer} event.
  224. */
  225. function safeTransferFrom(
  226. address from,
  227. address to,
  228. uint256 tokenId,
  229. bytes calldata data
  230. ) external;
  231. }
  232.  
  233. // File: @openzeppelin/contracts/utils/introspection/ERC165.sol
  234.  
  235.  
  236. // OpenZeppelin Contracts v4.4.0 (utils/introspection/ERC165.sol)
  237.  
  238. pragma solidity ^0.8.0;
  239.  
  240.  
  241. /**
  242. * @dev Implementation of the {IERC165} interface.
  243. *
  244. * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
  245. * for the additional interface-id that will be supported. For example:
  246. *
  247. * ```solidity
  248. * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
  249. * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
  250. * }
  251. * ```
  252. *
  253. * Alternatively, {ERC165Storage} provides an easier to-use but more expensive implementation.
  254. */
  255. abstract contract ERC165 is IERC165 {
  256. /**
  257. * @dev See {IERC165-supportsInterface}.
  258. */
  259. function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
  260. return interfaceId == type(IERC165).interfaceId;
  261. }
  262. }
  263.  
  264. // File: @openzeppelin/contracts/utils/Strings.sol
  265.  
  266.  
  267. // OpenZeppelin Contracts v4.4.0 (utils/Strings.sol)
  268.  
  269. pragma solidity ^0.8.0;
  270.  
  271. /**
  272. * @dev String operations.
  273. */
  274. library Strings {
  275. bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
  276.  
  277. /**
  278. * @dev Converts a `uint256` to its ASCII `string` decimal representation.
  279. */
  280. function toString(uint256 value) internal pure returns (string memory) {
  281. // Inspired by OraclizeAPI's implementation - MIT licence
  282. // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
  283.  
  284. if (value == 0) {
  285. return "0";
  286. }
  287. uint256 temp = value;
  288. uint256 digits;
  289. while (temp != 0) {
  290. digits++;
  291. temp /= 10;
  292. }
  293. bytes memory buffer = new bytes(digits);
  294. while (value != 0) {
  295. digits -= 1;
  296. buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
  297. value /= 10;
  298. }
  299. return string(buffer);
  300. }
  301.  
  302. /**
  303. * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
  304. */
  305. function toHexString(uint256 value) internal pure returns (string memory) {
  306. if (value == 0) {
  307. return "0x00";
  308. }
  309. uint256 temp = value;
  310. uint256 length = 0;
  311. while (temp != 0) {
  312. length++;
  313. temp >>= 8;
  314. }
  315. return toHexString(value, length);
  316. }
  317.  
  318. /**
  319. * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
  320. */
  321. function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
  322. bytes memory buffer = new bytes(2 * length + 2);
  323. buffer[0] = "0";
  324. buffer[1] = "x";
  325. for (uint256 i = 2 * length + 1; i > 1; --i) {
  326. buffer[i] = _HEX_SYMBOLS[value & 0xf];
  327. value >>= 4;
  328. }
  329. require(value == 0, "Strings: hex length insufficient");
  330. return string(buffer);
  331. }
  332. }
  333.  
  334. // File: @openzeppelin/contracts/access/IAccessControl.sol
  335.  
  336.  
  337. // OpenZeppelin Contracts v4.4.0 (access/IAccessControl.sol)
  338.  
  339. pragma solidity ^0.8.0;
  340.  
  341. /**
  342. * @dev External interface of AccessControl declared to support ERC165 detection.
  343. */
  344. interface IAccessControl {
  345. /**
  346. * @dev Emitted when `new admin role` is set as ``role``'s admin role, replacing `previousAdminRole`
  347. *
  348. * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
  349. * {RoleAdminChanged} not being emitted signaling this.
  350. *
  351. * _Available since v3.1._
  352. */
  353. event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
  354.  
  355. /**
  356. * @dev Emitted when `account` is granted `role`.
  357. *
  358. * `sender` is the account that originated the contract call, an admin role
  359. * bearer except when using {AccessControl-_setupRole}.
  360. */
  361. event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
  362.  
  363. /**
  364. * @dev Emitted when `account` is revoked `role`.
  365. *
  366. * `sender` is the account that originated the contract call:
  367. * - if using `revoke roles`, it is the admin role bearer
  368. * - if using `renounceRole`, it is the role bearer (i.e. `account`)
  369. */
  370. event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
  371.  
  372. /**
  373. * @dev Returns `true` if `account` has been granted `role`.
  374. */
  375. function hasRole(bytes32 role, address account) external view returns (bool);
  376.  
  377. /**
  378. * @dev Returns the admin role that controls `role`. See {grantRole} and
  379. * {revokeRole}.
  380. *
  381. * To change a role's admin, use {AccessControl-_setRoleAdmin}.
  382. */
  383. function getRoleAdmin(bytes32 role) external view returns (bytes32);
  384.  
  385. /**
  386. * @dev Grants `role` to `account`.
  387. *
  388. * If `account` had not been already granted `role`, emits a {RoleGranted}
  389. * event.
  390. *
  391. * Requirements:
  392. *
  393. * - The caller must have ``role``'s admin role.
  394. */
  395. function grantRole(bytes32 role, address account) external;
  396.  
  397. /**
  398. * @dev Revokes `role` from `account`.
  399. *
  400. * If `account` had been granted `role`, emits a {RoleRevoked} event.
  401. *
  402. * Requirements:
  403. *
  404. * - The caller must have ``role``'s admin role.
  405. */
  406. function revokeRole(bytes32 role, address account) external;
  407.  
  408. /**
  409. * @dev Revokes `role` from the calling account.
  410. *
  411. * Roles are often managed via {grantRole} and {revokeRole}: this function's
  412. * purpose is to provide a mechanism for accounts to lose their privileges
  413. * if they are compromised (such as when a trusted device is misplaced).
  414. *
  415. * If the calling account had been granted `role`, emits a {RoleRevoked}
  416. * event.
  417. *
  418. * Requirements:
  419. *
  420. * - the caller must be `account`.
  421. */
  422. function renounceRole(bytes32 role, address account) external;
  423. }
  424.  
  425. // File: @openzeppelin/contracts/utils/Context.sol
  426.  
  427.  
  428. // OpenZeppelin Contracts v4.4.0 (utils/Context.sol)
  429.  
  430. pragma solidity ^0.8.0;
  431.  
  432. /**
  433. * @dev Provides information about the current execution context, including the
  434. * sender of the transaction and its data. While these are generally available
  435. * via msg. sender and msg. data, they should not be accessed in such a direct
  436. * manner, since when dealing with meta-transactions the account sending and
  437. * paying for execution may not be the actual sender (as far as an application
  438. * is concerned).
  439. *
  440. * This contract is only required for intermediate, library-like contracts.
  441. */
  442. abstract contract Context {
  443. function _msgSender() internal view virtual returns (address) {
  444. return msg.sender;
  445. }
  446.  
  447. function _msgData() internal view virtual returns (bytes calldata) {
  448. return msg.data;
  449. }
  450. }
  451.  
  452. // File: @openzeppelin/contracts/access/AccessControl.sol
  453.  
  454.  
  455. // OpenZeppelin Contracts v4.4.0 (access/AccessControl.sol)
  456.  
  457. pragma solidity ^0.8.0;
  458.  
  459.  
  460.  
  461.  
  462.  
  463. /**
  464. * @dev Contract module that allows children to implement role-based access
  465. * control mechanisms. This is a lightweight version that doesn't allow enumerating role
  466. * members except through off-chain means by accessing the contract event logs. Some
  467. * applications may benefit from on-chain enumerability, for those cases see
  468. * {AccessControlEnumerable}.
  469. *
  470. * Roles are referred to by their `bytes32` identifier. These should be exposed
  471. * in the external API and be unique. The best way to achieve this is by
  472. * using `public constant` hash digests:
  473. *
  474. * ```
  475. * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
  476. * ```
  477. *
  478. * Roles can be used to represent a set of permissions. To restrict access to a
  479. * function call, use {hasRole}:
  480. *
  481. * ```
  482. * function foo() public {
  483. * require(hasRole(MY_ROLE, msg.sender));
  484. * ...
  485. * }
  486. * ```
  487. *
  488. * Roles can be granted and revoked dynamically via the {grantRole} and
  489. * {revokeRole} functions. Each role has an associated admin role, and only
  490. * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
  491. *
  492. * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
  493. * that only accounts with this role will be able to grant or revoke other
  494. * roles. More complex role relationships can be created by using
  495. * {_setRoleAdmin}.
  496. *
  497. * WARNING: The `DEFAULT_ADMIN_ROLE` is also its admin: it has permission to
  498. * grant and revoke this role. Extra precautions should be taken to secure
  499. * accounts that have been granted it.
  500. */
  501. abstract contract AccessControl is Context, IAccessControl, ERC165 {
  502. struct RoleData {
  503. mapping(address => bool) members;
  504. bytes32 adminRole;
  505. }
  506.  
  507. mapping(bytes32 => RoleData) private _roles;
  508.  
  509. bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
  510.  
  511. /**
  512. * @dev Modifier that checks that an account has a specific role. Reverts
  513. * with a standardized message including the required role.
  514. *
  515. * The format of the revert reason is given by the following regular expression:
  516. *
  517. * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
  518. *
  519. * _Available since v4.1._
  520. */
  521. modifier onlyRole(bytes32 role) {
  522. _checkRole(role, _msgSender());
  523. _;
  524. }
  525.  
  526. /**
  527. * @dev See {IERC165-supportsInterface}.
  528. */
  529. function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
  530. return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
  531. }
  532.  
  533. /**
  534. * @dev Returns `true` if `account` has been granted `role`.
  535. */
  536. function hasRole(bytes32 role, address account) public view override returns (bool) {
  537. return _roles[role].members[account];
  538. }
  539.  
  540. /**
  541. * @dev Revert with a standard message if `account` is missing `role`.
  542. *
  543. * The format of the revert reason is given by the following regular expression:
  544. *
  545. * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
  546. */
  547. function _checkRole(bytes32 role, address account) internal view {
  548. if (!hasRole(role, account)) {
  549. revert(
  550. string(
  551. abi.encodePacked(
  552. "AccessControl: account ",
  553. Strings.toHexString(uint160(account), 20),
  554. " is missing role ",
  555. Strings.toHexString(uint256(role), 32)
  556. )
  557. )
  558. );
  559. }
  560. }
  561.  
  562. /**
  563. * @dev Returns the admin role that controls `role`. See {grantRole} and
  564. * {revokeRole}.
  565. *
  566. * To change a role's admin, use {_setRoleAdmin}.
  567. */
  568. function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
  569. return _roles[role].adminRole;
  570. }
  571.  
  572. /**
  573. * @dev Grants `role` to `account`.
  574. *
  575. * If `account` had not been already granted `role`, emits a {RoleGranted}
  576. * event.
  577. *
  578. * Requirements:
  579. *
  580. * - The caller must have ``role``'s admin role.
  581. */
  582. function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
  583. _grantRole(role, account);
  584. }
  585.  
  586. /**
  587. * @dev Revokes `role` from `account`.
  588. *
  589. * If `account` had been granted `role`, emits a {RoleRevoked} event.
  590. *
  591. * Requirements:
  592. *
  593. * - The caller must have ``role``'s admin role.
  594. */
  595. function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
  596. _revokeRole(role, account);
  597. }
  598.  
  599. /**
  600. * @dev Revokes `role` from the calling account.
  601. *
  602. * Roles are often managed via {grantRole} and {revokeRole}: this function's
  603. * purpose is to provide a mechanism for accounts to lose their privileges
  604. * if they are compromised (such as when a trusted device is misplaced).
  605. *
  606. * If the calling account had been revoked `role`, emits a {RoleRevoked}
  607. * event.
  608. *
  609. * Requirements:
  610. *
  611. * - the caller must be `account`.
  612. */
  613. function renounceRole(bytes32 role, address account) public virtual override {
  614. require(account == _msgSender(), "AccessControl: can only renounce roles for self");
  615.  
  616. _revokeRole(role, account);
  617. }
  618.  
  619. /**
  620. * @dev Grants `role` to `account`.
  621. *
  622. * If `account` had not been already granted `role`, emits a {RoleGranted}
  623. * event. Note that unlike {grantRole}, this function doesn't perform any
  624. * checks on the calling account.
  625. *
  626. * [WARNING]
  627. * ====
  628. * This function should only be called from the constructor when setting
  629. * up the initial roles for the system.
  630. *
  631. * Using this function in any other way is effectively circumventing the admin
  632. * system imposed by {AccessControl}.
  633. * ====
  634. *
  635. * NOTE: This function is deprecated in favor of {_grantRole}.
  636. */
  637. function _setupRole(bytes32 role, address account) internal virtual {
  638. _grantRole(role, account);
  639. }
  640.  
  641. /**
  642. * @dev Sets `admin role` as ``role``'s admin role.
  643. *
  644. * Emits a {RoleAdminChanged} event.
  645. */
  646. function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
  647. bytes32 previousAdminRole = getRoleAdmin(role);
  648. _roles[role].adminRole = adminRole;
  649. emit RoleAdminChanged(role, previousAdminRole, adminRole);
  650. }
  651.  
  652. /**
  653. * @dev Grants `role` to `account`.
  654. *
  655. * Internal function without access restriction.
  656. */
  657. function _grantRole(bytes32 role, address account) internal virtual {
  658. if (!hasRole(role, account)) {
  659. _roles[role].members[account] = true;
  660. emit RoleGranted(role, account, _msgSender());
  661. }
  662. }
  663.  
  664. /**
  665. * @dev Revokes `role` from `account`.
  666. *
  667. * Internal function without access restriction.
  668. */
  669. function _revokeRole(bytes32 role, address account) internal virtual {
  670. if (hasRole(role, account)) {
  671. _roles[role].members[account] = false;
  672. emit RoleRevoked(role, account, _msgSender());
  673. }
  674. }
  675. }
  676.  
  677. // File: @openzeppelin/contracts/token/ERC20/IERC20.sol
  678.  
  679.  
  680. // OpenZeppelin Contracts v4.4.0 (token/ERC20/IERC20.sol)
  681.  
  682. pragma solidity ^0.8.0;
  683.  
  684. /**
  685. * @dev Interface of the ERC20 standard as defined in the EIP.
  686. */
  687. interface IERC20 {
  688. /**
  689. * @dev Returns the number of tokens in existence.
  690. */
  691. function totalSupply() external view returns (uint256);
  692.  
  693. /**
  694. * @dev Returns the number of tokens owned by `account`.
  695. */
  696. function balanceOf(address account) external view returns (uint256);
  697.  
  698. /**
  699. * @dev Moves `amount` tokens from the caller's account to `recipient`.
  700. *
  701. * Returns a boolean value indicating whether the operation succeeded.
  702. *
  703. * Emits a {Transfer} event.
  704. */
  705. function transfer(address recipient, uint256 amount) external returns (bool);
  706.  
  707. /**
  708. * @dev Returns the remaining number of tokens that `spender` will be
  709. * allowed to spend on behalf of `owner` through {transferFrom}. This is
  710. * zero by default.
  711. *
  712. * This value changes when {approve} or {transferFrom} are called.
  713. */
  714. function allowance(address owner, address spender) external view returns (uint256);
  715.  
  716. /**
  717. * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
  718. *
  719. * Returns a boolean value indicating whether the operation succeeded.
  720. *
  721. * IMPORTANT: Beware that changing an allowance with this method brings the risk
  722. * that someone may use both the old and the new allowance by unfortunate
  723. * transaction ordering. One possible solution to mitigate this race
  724. * condition is to first reduce the spender's allowance to 0 and set the
  725. * desired value afterward:
  726. * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
  727. *
  728. * Emits an {Approval} event.
  729. */
  730. function approve(address spender, uint256 amount) external returns (bool);
  731.  
  732. /**
  733. * @dev Moves `amount` tokens from `sender` to `recipient` using the
  734. * allowance mechanism. `amount` is then deducted from the caller's
  735. * allowance.
  736. *
  737. * Returns a boolean value indicating whether the operation succeeded.
  738. *
  739. * Emits a {Transfer} event.
  740. */
  741. function transferFrom(
  742. address sender,
  743. address recipient,
  744. uint256 amount
  745. ) external returns (bool);
  746.  
  747. /**
  748. * @dev Emitted when `value` tokens are moved from one account (`from`) to
  749. * another (`to`).
  750. *
  751. * Note that `value` may be zero.
  752. */
  753. event Transfer(address indexed from, address indexed to, uint256 value);
  754.  
  755. /**
  756. * @dev Emitted when the allowance of a `spender` for an `owner` is set by
  757. * a call to {approve}. `value` is the new allowance.
  758. */
  759. event Approval(address indexed owner, address indexed spender, uint256 value);
  760. }
  761.  
  762. // File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol
  763.  
  764.  
  765. // OpenZeppelin Contracts v4.4.0 (token/ERC20/extensions/IERC20Metadata.sol)
  766.  
  767. pragma solidity ^0.8.0;
  768.  
  769.  
  770. /**
  771. * @dev Interface for the optional metadata functions from the ERC20 standard.
  772. *
  773. * _Available since v4.1._
  774. */
  775. interface IERC20Metadata is IERC20 {
  776. /**
  777. * @dev Returns the name of the token.
  778. */
  779. function name() external view returns (string memory);
  780.  
  781. /**
  782. * @dev Returns the symbol of the token.
  783. */
  784. function symbol() external view returns (string memory);
  785.  
  786. /**
  787. * @dev Returns the decimals places of the token.
  788. */
  789. function decimals() external view returns (uint8);
  790. }
  791.  
  792. // File: @openzeppelin/contracts/token/ERC20/ERC20.sol
  793.  
  794.  
  795. // OpenZeppelin Contracts v4.4.0 (token/ERC20/ERC20.sol)
  796.  
  797. pragma solidity ^0.8.0;
  798.  
  799.  
  800.  
  801.  
  802. /**
  803. * @dev Implementation of the {IERC20} interface.
  804. *
  805. * This implementation is agnostic to the way tokens are created. This means
  806. * that a supply mechanism has to be added in a derived contract using {_mint}.
  807. * For a generic mechanism see {ERC20PresetMinterPauser}.
  808. *
  809. * TIP: For a detailed writeup see our guide
  810. * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
  811. * to implement supply mechanisms].
  812. *
  813. * We have followed general OpenZeppelin Contracts guidelines: functions revert
  814. * instead returning `false` on failure. This behavior is nonetheless
  815. * conventional and does not conflict with the expectations of ERC20
  816. * applications.
  817. *
  818. * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
  819. * This allows applications to reconstruct the allowance for all accounts just
  820. * by listening to said events. Other implementations of the EIP may not emit
  821. * these events, as it isn't required by the specification.
  822. *
  823. * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
  824. * functions have been added to mitigate the well-known issues around setting
  825. * allowances. See {IERC20-approve}.
  826. */
  827. contract ERC20 is Context, IERC20, IERC20Metadata {
  828. mapping(address => uint256) private _balances;
  829.  
  830. mapping(address => mapping(address => uint256)) private _allowances;
  831.  
  832. uint256 private _totalSupply;
  833.  
  834. string private _name;
  835. string private _symbol;
  836.  
  837. /**
  838. * @dev Sets the values for {name} and {symbol}.
  839. *
  840. * The default value of {decimals} is 18. To select a different value for
  841. * {decimals} you should overload it.
  842. *
  843. * All two of these values are immutable: they can only be set once during
  844. * construction.
  845. */
  846. constructor(string memory name_, string memory symbol_) {
  847. _name = name_;
  848. _symbol = symbol_;
  849. }
  850.  
  851. /**
  852. * @dev Returns the name of the token.
  853. */
  854. function name() public view virtual override returns (string memory) {
  855. return _name;
  856. }
  857.  
  858. /**
  859. * @dev Returns the symbol of the token, usually a shorter version of the
  860. * name.
  861. */
  862. function symbol() public view virtual override returns (string memory) {
  863. return _symbol;
  864. }
  865.  
  866. /**
  867. * @dev Returns the number of decimals used to get its user representation.
  868. * For example, if `decimals` equals `2`, a balance of `505` tokens should
  869. * be displayed to a user as `5.05` (`505 / 10 ** 2`).
  870. *
  871. * Tokens usually opt for a value of 18, imitating the relationship between
  872. * Ether and Wei. This is the value {ERC20} uses, unless this function is
  873. * overridden;
  874. *
  875. * NOTE: This information is only used for _display_ purposes: it in
  876. * no way affects any of the arithmetic of the contract, including
  877. * {IERC20-balanceOf} and {IERC20-transfer}.
  878. */
  879. function decimals() public view virtual override returns (uint8) {
  880. return 18;
  881. }
  882.  
  883. /**
  884. * @dev See {IERC20-totalSupply}.
  885. */
  886. function totalSupply() public view virtual override returns (uint256) {
  887. return _totalSupply;
  888. }
  889.  
  890. /**
  891. * @dev See {IERC20-balanceOf}.
  892. */
  893. function balanceOf(address account) public view virtual override returns (uint256) {
  894. return _balances[account];
  895. }
  896.  
  897. /**
  898. * @dev See {IERC20-transfer}.
  899. *
  900. * Requirements:
  901. *
  902. * - `recipient` cannot be the zero address.
  903. * - the caller must have a balance of at least `amount`.
  904. */
  905. function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
  906. _transfer(_msgSender(), recipient, amount);
  907. return true;
  908. }
  909.  
  910. /**
  911. * @dev See {IERC20-allowance}.
  912. */
  913. function allowance(address owner, address spender) public view virtual override returns (uint256) {
  914. return _allowances[owner][spender];
  915. }
  916.  
  917. /**
  918. * @dev See {IERC20-approve}.
  919. *
  920. * Requirements:
  921. *
  922. * - `spender` cannot be the zero address.
  923. */
  924. function approve(address spender, uint256 amount) public virtual override returns (bool) {
  925. _approve(_msgSender(), spender, amount);
  926. return true;
  927. }
  928.  
  929. /**
  930. * @dev See {IERC20-transferFrom}.
  931. *
  932. * Emits an {Approval} event indicating the updated allowance. This is not
  933. * required by the EIP. See the note at the beginning of {ERC20}.
  934. *
  935. * Requirements:
  936. *
  937. * - `sender` and `recipient` cannot be the zero address.
  938. * - `sender` must have a balance of at least `amount`.
  939. * - The caller must have an allowance for ``sender``'s tokens of at least
  940. * `amount`.
  941. */
  942. function transferFrom(
  943. address sender,
  944. address recipient,
  945. uint256 amount
  946. ) public virtual override returns (bool) {
  947. _transfer(sender, recipient, amount);
  948.  
  949. uint256 currentAllowance = _allowances[sender][_msgSender()];
  950. require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
  951. unchecked {
  952. _approve(sender, _msgSender(), currentAllowance - amount);
  953. }
  954.  
  955. return true;
  956. }
  957.  
  958. /**
  959. * @dev Atomically increases the allowance granted to `spender` by the caller.
  960. *
  961. * This is an alternative to {approve} that can be used as mitigation for
  962. * problems described in {IERC20-approve}.
  963. *
  964. * Emits an {Approval} event indicating the updated allowance.
  965. *
  966. * Requirements:
  967. *
  968. * - `spender` cannot be the zero address.
  969. */
  970. function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
  971. _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
  972. return true;
  973. }
  974.  
  975. /**
  976. * @dev Atomically decreases the allowance granted to `spender` by the caller.
  977. *
  978. * This is an alternative to {approve} that can be used as mitigation for
  979. * problems described in {IERC20-approve}.
  980. *
  981. * Emits an {Approval} event indicating the updated allowance.
  982. *
  983. * Requirements:
  984. *
  985. * - `spender` cannot be the zero address.
  986. * - `spender` must have an allowance for the caller of at least
  987. * `subtracted value`.
  988. */
  989. function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
  990. uint256 currentAllowance = _allowances[_msgSender()][spender];
  991. require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
  992. unchecked {
  993. _approve(_msgSender(), spender, currentAllowance - subtractedValue);
  994. }
  995.  
  996. return true;
  997. }
  998.  
  999. /**
  1000. * @dev Moves `amount` of tokens from `sender` to `recipient`.
  1001. *
  1002. * This internal function is equivalent to {transfer} and can be used to
  1003. * e.g. implement automatic token fees, slashing mechanisms, etc.
  1004. *
  1005. * Emits a {Transfer} event.
  1006. *
  1007. * Requirements:
  1008. *
  1009. * - `sender` cannot be the zero address.
  1010. * - `recipient` cannot be the zero address.
  1011. * - `sender` must have a balance of at least `amount`.
  1012. */
  1013. function _transfer(
  1014. address sender,
  1015. address recipient,
  1016. uint256 amount
  1017. ) internal virtual {
  1018. require(sender != address(0), "ERC20: transfer from the zero address");
  1019. require(recipient != address(0), "ERC20: transfer to the zero address");
  1020.  
  1021. _beforeTokenTransfer(sender, recipient, amount);
  1022.  
  1023. uint256 senderBalance = _balances[sender];
  1024. require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
  1025. unchecked {
  1026. _balances[sender] = senderBalance - amount;
  1027. }
  1028. _balances[recipient] += amount;
  1029.  
  1030. emit Transfer(sender, recipient, amount);
  1031.  
  1032. _afterTokenTransfer(sender, recipient, amount);
  1033. }
  1034.  
  1035. /** @dev Creates `amount` tokens and assigns them to `account`, increasing
  1036. * the total supply.
  1037. *
  1038. * Emits a {Transfer} event with `from` set to the zero address.
  1039. *
  1040. * Requirements:
  1041. *
  1042. * - `account` cannot be the zero address.
  1043. */
  1044. function _mint(address account, uint256 amount) internal virtual {
  1045. require(account != address(0), "ERC20: mint to the zero address");
  1046.  
  1047. _beforeTokenTransfer(address(0), account, amount);
  1048.  
  1049. _totalSupply += amount;
  1050. _balances[account] += amount;
  1051. emit Transfer(address(0), account, amount);
  1052.  
  1053. _afterTokenTransfer(address(0), account, amount);
  1054. }
  1055.  
  1056. /**
  1057. * @dev Destroys `amount` tokens from `account`, reducing the
  1058. * total supply.
  1059. *
  1060. * Emits a {Transfer} event with `to` set to the zero address.
  1061. *
  1062. * Requirements:
  1063. *
  1064. * - `account` cannot be the zero address.
  1065. * - `account` must have at least `amount` tokens.
  1066. */
  1067. function _burn(address account, uint256 amount) internal virtual {
  1068. require(account != address(0), "ERC20: burn from the zero address");
  1069.  
  1070. _beforeTokenTransfer(account, address(0), amount);
  1071.  
  1072. uint256 accountBalance = _balances[account];
  1073. require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
  1074. unchecked {
  1075. _balances[account] = accountBalance - amount;
  1076. }
  1077. _totalSupply -= amount;
  1078.  
  1079. emit Transfer(account, address(0), amount);
  1080.  
  1081. _afterTokenTransfer(account, address(0), amount);
  1082. }
  1083.  
  1084. /**
  1085. * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
  1086. *
  1087. * This internal function is equivalent to `approve`, and can be used to
  1088. * e.g. set automatic allowances for specific subsystems, etc.
  1089. *
  1090. * Emits an {Approval} event.
  1091. *
  1092. * Requirements:
  1093. *
  1094. * - `owner` cannot be the zero address.
  1095. * - `spender` cannot be the zero address.
  1096. */
  1097. function _approve(
  1098. address owner,
  1099. address spender,
  1100. uint256 amount
  1101. ) internal virtual {
  1102. require(owner != address(0), "ERC20: approve from the zero address");
  1103. require(spender != address(0), "ERC20: approve to the zero address");
  1104.  
  1105. _allowances[owner][spender] = amount;
  1106. emit Approval(owner, spender, amount);
  1107. }
  1108.  
  1109. /**
  1110. * @dev Hook that is called before any transfer of tokens. This includes
  1111. * minting and burning.
  1112. *
  1113. * Calling conditions:
  1114. *
  1115. * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
  1116. * will be transferred to `to`.
  1117. * - when `from` is zero, `amount` tokens will be minted for `to`.
  1118. * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
  1119. * - `from` and `to` are never both zero.
  1120. *
  1121. * To learn more about hooks, head to Xref:ROOT: extending contracts.adoc#using-hooks[Using Hooks].
  1122. */
  1123. function _beforeTokenTransfer(
  1124. address from,
  1125. address to,
  1126. uint256 amount
  1127. ) internal virtual {}
  1128.  
  1129. /**
  1130. * @dev Hook that is called after any transfer of tokens. This includes
  1131. * minting and burning.
  1132. *
  1133. * Calling conditions:
  1134. *
  1135. * - when `from` and `to` are both non-zero, `the amount` of ``from``'s tokens
  1136. * has been transferred to `to`.
  1137. * - when `from` is zero, `amount` tokens have been minted for `to`.
  1138. * - when `to` is zero, the `amount` of ``from``'s tokens has been burned.
  1139. * - `from` and `to` are never both zero.
  1140. *
  1141. * To learn more about hooks, head to Xref:ROOT: extending contracts.adoc#using-hooks[Using Hooks].
  1142. */
  1143. function _afterTokenTransfer(
  1144. address from,
  1145. address to,
  1146. uint256 amount
  1147. ) internal virtual {}
  1148. }
  1149.  
  1150. // File: contracts/SpeciesCoin.sol
  1151.  
  1152.  
  1153. pragma solidity ^0.8.0;
  1154.  
  1155.  
  1156.  
  1157.  
  1158.  
  1159. contract DarkCoin is ERC20, AccessControl, ERC721Holder {
  1160. bytes32 public constant CONTRACT_ADMIN_ROLE = keccak256("CONTRACT_ADMIN_ROLE");
  1161. bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
  1162. bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
  1163. address public collectionAddress;
  1164. uint256 public numberOfBlocksPerRewardUnit;
  1165. uint256 public coinAmountPerRewardUnit;
  1166. uint256 public welcomeBonusAmount;
  1167. uint256 public amountOfStakers;
  1168. uint256 public tokensStaked;
  1169. uint256 immutable public contractCreationBlock;
  1170.  
  1171. struct StakeInfo {
  1172. uint256 stakedAtBlock;
  1173. uint256 lastHarvestBlock;
  1174. bool currentlyStaked;
  1175. }
  1176. /// owner => tokenId => StakeInfo
  1177. mapping (address => mapping(uint256 => StakeInfo)) public stakeLog;
  1178. /// owner => #NFTsStaked
  1179. mapping (address => uint256) public tokensStakedByUser;
  1180. /// tokenId => true/false (true if welcome bonus has been collected for a specific tokenId)
  1181. mapping (uint256 => bool) public welcomeBonusCollected;
  1182. /// owner => list of all tokenIds that the user has staked
  1183. mapping (address => uint256[]) public stakePortfolioByUser;
  1184. /// tokenId => indexInStakePortfolio
  1185. mapping(uint256 => uint256) public indexOfTokenIdInStakePortfolio;
  1186.  
  1187. event RewardsHarvested (address owner, uint256 amount);
  1188. event NFTStaked (address owner, uint256 tokenId);
  1189. event NFTUnstaked (address owner, uint256 tokenId);
  1190.  
  1191. constructor(address owner, address _collectionAddress) ERC20("Dark Coin", "DRK") AccessControl(){
  1192. _mint(owner, 99999999999999999200000 * 10 ** 18);
  1193. _setupRole(DEFAULT_ADMIN_ROLE, owner);
  1194. _setupRole(CONTRACT_ADMIN_ROLE, owner);
  1195. _setupRole(BURNER_ROLE, owner);
  1196. _setupRole(MINTER_ROLE, owner);
  1197. collectionAddress = _collectionAddress;
  1198. contractCreationBlock = block.number;
  1199. coinAmountPerRewardUnit = 1 * 10 ** 18; // 1 ERC20 coins per rewardUnit, may be changed later on
  1200. numberOfBlocksPerRewardUnit = 20571; // 12 hours per reward unit , may be changed later on
  1201. welcomeBonusAmount = 200 * 10 ** 18; // 200 Coins welcome bonus, only paid once per tokenId
  1202. }
  1203.  
  1204. function stakedNFTSByUser(address owner) external view returns (uint256[] memory){
  1205. return stakePortfolioByUser[owner];
  1206. }
  1207.  
  1208. function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
  1209. _mint(to, amount);
  1210. }
  1211.  
  1212. function burn(address from, uint256 amount) external onlyRole(BURNER_ROLE) {
  1213. super._burn(from, amount);
  1214. }
  1215.  
  1216. function pendingRewards(address owner, uint256 tokenId) public view returns (uint256){
  1217. StakeInfo memory info = stakeLog[owner][tokenId];
  1218.  
  1219. if(info.lastHarvestBlock < contractCreationBlock || info.currentlyStaked == false) {
  1220. return 0;
  1221. }
  1222. uint256 blocksPassedSinceLastHarvest = block.number - info.lastHarvestBlock;
  1223. if (blocksPassedSinceLastHarvest < numberOfBlocksPerRewardUnit * 2) {
  1224. return 0;
  1225. }
  1226. uint256 rewardAmount = blocksPassedSinceLastHarvest / numberOfBlocksPerRewardUnit - 1;
  1227. return rewardAmount * coinAmountPerRewardUnit;
  1228.  
  1229. }
  1230.  
  1231. function stake(uint256 tokenId) public {
  1232. IERC721(collectionAddress).safeTransferFrom(_msgSender(), address(this), tokenId);
  1233. require(IERC721(collectionAddress).ownerOf(tokenId) == address(this),
  1234. "DRK: Error while transferring token");
  1235. StakeInfo storage info = stakeLog[_msgSender()][tokenId];
  1236. info.stakedAtBlock = block.number;
  1237. info.lastHarvestBlock = block.number;
  1238. info.currentlyStaked = true;
  1239. if(tokensStakedByUser[_msgSender()] == 0){
  1240. amountOfStakers += 1;
  1241. }
  1242. tokensStakedByUser[_msgSender()] += 1;
  1243. tokensStaked += 1;
  1244. stakePortfolioByUser[_msgSender()].push(tokenId);
  1245. uint256 indexOfNewElement = stakePortfolioByUser[_msgSender()].length - 1;
  1246. indexOfTokenIdInStakePortfolio[tokenId] = indexOfNewElement;
  1247. if(!welcomeBonusCollected[tokenId]) {
  1248. _mint(_msgSender(), welcomeBonusAmount);
  1249. welcomeBonusCollected[tokenId] = true;
  1250. }
  1251.  
  1252. emit NFTStaked(_msgSender(), tokenId);
  1253. }
  1254.  
  1255. function stakeBatch(uint256[] memory tokenIds) external {
  1256. for(uint currentId = 0; currentId < tokenIds.length; currentId++) {
  1257. if(tokenIds[currentId] == 0) {
  1258. continue;
  1259. }
  1260. stake(tokenIds[currentId]);
  1261. }
  1262. }
  1263.  
  1264. function unstakeBatch(uint256[] memory tokenIds) external {
  1265. for(uint currentId = 0; currentId < tokenIds.length; currentId++) {
  1266. if(tokenIds[currentId] == 0) {
  1267. continue;
  1268. }
  1269. unstake(tokenIds[currentId]);
  1270. }
  1271. }
  1272.  
  1273. function unstake(uint256 tokenId) public {
  1274. if(pendingRewards(_msgSender(), tokenId) > 0){
  1275. harvest(tokenId);
  1276. }
  1277. StakeInfo storage info = stakeLog[_msgSender()][tokenId];
  1278. info.currentlyStaked = true;
  1279. IERC721(collectionAddress).safeTransferFrom(address(this), _msgSender(), tokenId);
  1280. require(IERC721(collectionAddress).ownerOf(tokenId) == _msgSender(),
  1281. "SPCC: Error while transferring token");
  1282. if(tokensStakedByUser[_msgSender()] == 1){
  1283. amountOfStakers -= 1;
  1284. }
  1285. tokensStakedByUser[_msgSender()] -= 1;
  1286. tokensStaked -= 1;
  1287. stakePortfolioByUser[_msgSender()][indexOfTokenIdInStakePortfolio[tokenId]] = 0;
  1288. emit NFTUnstaked(_msgSender(), tokenId);
  1289. }
  1290.  
  1291. function harvest(uint256 tokenId) public {
  1292. StakeInfo storage info = stakeLog[_msgSender()][tokenId];
  1293. uint256 rewardAmountInERC20Tokens = pendingRewards(_msgSender(), tokenId);
  1294. if(rewardAmountInERC20Tokens > 0) {
  1295. info.lastHarvestBlock = block.number;
  1296. _mint(_msgSender(), rewardAmountInERC20Tokens);
  1297. emit RewardsHarvested(_msgSender(), rewardAmountInERC20Tokens);
  1298. }
  1299. }
  1300.  
  1301. function harvestBatch(address user) external {
  1302. uint256[] memory tokenIds = stakePortfolioByUser[user];
  1303.  
  1304. for(uint currentId = 0; currentId < tokenIds.length; currentId++) {
  1305. if(tokenIds[currentId] == 0) {
  1306. continue;
  1307. }
  1308. harvest(tokenIds[currentId]);
  1309. }
  1310. }
  1311.  
  1312. // ADMIN / SETTER FUNCTIONS
  1313. function setNumberOfBlocksPerRewardUnit(uint256 numberOfBlocks) external onlyRole(CONTRACT_ADMIN_ROLE){
  1314. numberOfBlocksPerRewardUnit = numberOfBlocks;
  1315. }
  1316.  
  1317. // parameter value must be supplied with 18 zeros.....
  1318. // e.g.: 1 token = setCoinAmountPerRewardUnit(1000000000000000000)
  1319. function setCoinAmountPerRewardUnit(uint256 coinAmount) external onlyRole(CONTRACT_ADMIN_ROLE){
  1320. coinAmountPerRewardUnit = coinAmount;
  1321. }
  1322.  
  1323. // same as setCoinAmountPerRewardUnit()
  1324. function setWelcomeBonusAmount(uint256 coinAmount) external onlyRole(CONTRACT_ADMIN_ROLE){
  1325. welcomeBonusAmount = coinAmount;
  1326. }
  1327.  
  1328. function setCollectionAddress(address newAddress) external onlyRole(CONTRACT_ADMIN_ROLE){
  1329. require (newAddress != address(0), "DRK: update to zero address not possible");
  1330. collectionAddress = newAddress;
  1331. }
  1332. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement