More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 158 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Claim Reward | 17425776 | 558 days ago | IN | 0 ETH | 0.00249848 | ||||
Claim Reward | 17387697 | 563 days ago | IN | 0 ETH | 0.00749354 | ||||
Claim Reward | 17342633 | 570 days ago | IN | 0 ETH | 0.00273428 | ||||
Claim Reward | 17335921 | 571 days ago | IN | 0 ETH | 0.00410744 | ||||
Claim Reward | 17327499 | 572 days ago | IN | 0 ETH | 0.00526217 | ||||
Claim Reward | 17326207 | 572 days ago | IN | 0 ETH | 0.00354072 | ||||
Claim Reward | 17027481 | 614 days ago | IN | 0 ETH | 0.00347467 | ||||
Claim Reward | 16896841 | 633 days ago | IN | 0 ETH | 0.00330494 | ||||
Claim Reward | 16867911 | 637 days ago | IN | 0 ETH | 0.00198481 | ||||
Claim Reward | 16848748 | 639 days ago | IN | 0 ETH | 0.00311051 | ||||
Claim Reward | 16847345 | 640 days ago | IN | 0 ETH | 0.00300502 | ||||
Claim Reward | 16839402 | 641 days ago | IN | 0 ETH | 0.00239793 | ||||
Claim Reward | 16833064 | 642 days ago | IN | 0 ETH | 0.00380959 | ||||
Claim Reward | 16812847 | 645 days ago | IN | 0 ETH | 0.00359298 | ||||
Claim Reward | 16803116 | 646 days ago | IN | 0 ETH | 0.01984229 | ||||
Claim Reward | 16787989 | 648 days ago | IN | 0 ETH | 0.00344449 | ||||
Claim Reward | 16760732 | 652 days ago | IN | 0 ETH | 0.00227856 | ||||
Claim Reward | 16760707 | 652 days ago | IN | 0 ETH | 0.00203466 | ||||
Claim Reward | 16722848 | 657 days ago | IN | 0 ETH | 0.00514286 | ||||
Claim Reward | 16715216 | 658 days ago | IN | 0 ETH | 0.00527011 | ||||
Claim Reward | 16695346 | 661 days ago | IN | 0 ETH | 0.00369937 | ||||
Claim Reward | 16691258 | 662 days ago | IN | 0 ETH | 0.00653975 | ||||
Claim Reward | 16690735 | 662 days ago | IN | 0 ETH | 0.00320244 | ||||
Claim Reward | 16690704 | 662 days ago | IN | 0 ETH | 0.00307399 | ||||
Claim Reward | 16690076 | 662 days ago | IN | 0 ETH | 0.00299746 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
15538304 | 823 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
SMOLNftRewards
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-11-19 */ /** *Submitted for verification at Etherscan.io on 2022-09-15 */ // File @openzeppelin/contracts/utils/introspection/[email protected] // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File @openzeppelin/contracts/token/ERC721/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer( address indexed from, address indexed to, uint256 indexed tokenId ); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval( address indexed owner, address indexed approved, uint256 indexed tokenId ); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll( address indexed owner, address indexed operator, bool approved ); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; } // File @openzeppelin/contracts/token/ERC721/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, 'Address: insufficient balance'); (bool success, ) = recipient.call{ value: amount }(''); require( success, 'Address: unable to send value, recipient may have reverted' ); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, 'Address: low-level call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, 'Address: low-level call with value failed' ); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require( address(this).balance >= value, 'Address: insufficient balance for call' ); require(isContract(target), 'Address: call to non-contract'); (bool success, bytes memory returndata) = target.call{ value: value }(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, 'Address: low-level static call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), 'Address: static call to non-contract'); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall( target, data, 'Address: low-level delegate call failed' ); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), 'Address: delegate call to non-contract'); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = '0123456789abcdef'; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return '0'; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return '0x00'; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = '0'; buffer[1] = 'x'; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, 'Strings: hex length insufficient'); return string(buffer); } } // File @openzeppelin/contracts/utils/introspection/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File @openzeppelin/contracts/token/ERC721/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), 'ERC721: balance query for the zero address'); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), 'ERC721: owner query for nonexistent token'); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require( _exists(tokenId), 'ERC721Metadata: URI query for nonexistent token' ); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ''; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ''; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, 'ERC721: approval to current owner'); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), 'ERC721: approve caller is not owner nor approved for all' ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), 'ERC721: approved query for nonexistent token'); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require( _isApprovedOrOwner(_msgSender(), tokenId), 'ERC721: transfer caller is not owner nor approved' ); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ''); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require( _isApprovedOrOwner(_msgSender(), tokenId), 'ERC721: transfer caller is not owner nor approved' ); _safeTransfer(from, to, tokenId, _data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require( _checkOnERC721Received(from, to, tokenId, _data), 'ERC721: transfer to non ERC721Receiver implementer' ); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), 'ERC721: operator query for nonexistent token'); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ''); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), 'ERC721: transfer to non ERC721Receiver implementer' ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), 'ERC721: mint to the zero address'); require(!_exists(tokenId), 'ERC721: token already minted'); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require( ERC721.ownerOf(tokenId) == from, 'ERC721: transfer from incorrect owner' ); require(to != address(0), 'ERC721: transfer to the zero address'); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits a {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, 'ERC721: approve to caller'); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert('ERC721: transfer to non ERC721Receiver implementer'); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Burnable.sol) pragma solidity ^0.8.0; /** * @title ERC721 Burnable Token * @dev ERC721 Token that can be irreversibly burned (destroyed). */ abstract contract ERC721Burnable is Context, ERC721 { /** * @dev Burns `tokenId`. See {ERC721-_burn}. * * Requirements: * * - The caller must own `tokenId` or be an approved operator. */ function burn(uint256 tokenId) public virtual { //solhint-disable-next-line max-line-length require( _isApprovedOrOwner(_msgSender(), tokenId), 'ERC721Burnable: caller is not owner nor approved' ); _burn(tokenId); } } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require( index < ERC721.balanceOf(owner), 'ERC721Enumerable: owner index out of bounds' ); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require( index < ERC721Enumerable.totalSupply(), 'ERC721Enumerable: global index out of bounds' ); return _allTokens[index]; } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override { super._beforeTokenTransfer(from, to, tokenId); if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } } // File @openzeppelin/contracts/security/[email protected] // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), 'Pausable: paused'); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), 'Pausable: not paused'); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Pausable.sol) pragma solidity ^0.8.0; /** * @dev ERC721 token with pausable token transfers, minting and burning. * * Useful for scenarios such as preventing trades until the end of an evaluation * period, or having an emergency switch for freezing all token transfers in the * event of a large bug. */ abstract contract ERC721Pausable is ERC721, Pausable { /** * @dev See {ERC721-_beforeTokenTransfer}. * * Requirements: * * - the contract must not be paused. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override { super._beforeTokenTransfer(from, to, tokenId); require(!paused(), 'ERC721Pausable: token transfer while paused'); } } // File @openzeppelin/contracts/access/[email protected] // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), 'Ownable: caller is not the owner'); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), 'Ownable: new owner is the zero address'); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, 'Counter: decrement overflow'); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } // File @openzeppelin/contracts/token/ERC20/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File @openzeppelin/contracts/interfaces/[email protected] // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; // File contracts/interfaces/ISmoltingInu.sol pragma solidity ^0.8.9; /** * @dev SmoltingInu token interface */ interface ISmoltingInu is IERC20 { function gameMint(address _user, uint256 _amount) external; function gameBurn(address _user, uint256 _amount) external; function addPlayThrough( address _user, uint256 _amountWagered, uint8 _percentContribution ) external; function setCanSellWithoutElevation(address _wallet, bool _canSellWithoutElev) external; } // File contracts/interfaces/ISMOLNftRewards.sol pragma solidity ^0.8.9; interface ISMOLNftRewards { function claimReward() external; function depositRewards(uint256 _amount) external; function getShares(address wallet) external view returns (uint256); } // File contracts/SMOLNftRewards.sol pragma solidity ^0.8.9; contract SMOLNftRewards is ISMOLNftRewards, Ownable { struct Reward { uint256 totalExcluded; // excluded reward uint256 totalRealised; uint256 lastClaim; // used for boosting logic } struct Share { uint256 amount; uint256 stakedTime; } IERC721 shareholderNFT; ISmoltingInu smol = ISmoltingInu(0x553539d40AE81FD0d9C4b991B0b77bE6f6Bc030e); uint256 public totalStakedUsers; uint256 public totalSharesDeposited; // will only be actual deposited tokens without handling any reflections or otherwise // amount of shares a user has mapping(address => Share) shares; // reward information per user mapping(address => Reward) public rewards; uint256 public totalRewards; uint256 public totalDistributed; uint256 public rewardsPerShare; uint256 private constant ACC_FACTOR = 10**36; event ClaimReward(address user); event DistributeReward(address indexed user); event DepositRewards(address indexed user, uint256 amountTokens); modifier onlyToken() { require(msg.sender == address(shareholderNFT), 'must be token contract'); _; } constructor(address _shareholderNFT) { shareholderNFT = IERC721(_shareholderNFT); } function setShare(address shareholder, uint256 newBalance) external onlyToken { // _addShares and _removeShares takes the amount to add or remove respectively, // so we should handle the diff from the new balance when passing in the amounts // to these functions if (shares[shareholder].amount > newBalance) { _removeShares(shareholder, shares[shareholder].amount - newBalance); } else if (shares[shareholder].amount < newBalance) { _addShares(shareholder, newBalance - shares[shareholder].amount); } } function _addShares(address shareholder, uint256 amount) private { if (shares[shareholder].amount > 0) { _distributeReward(shareholder); } uint256 sharesBefore = shares[shareholder].amount; totalSharesDeposited += amount; shares[shareholder].amount += amount; shares[shareholder].stakedTime = block.timestamp; if (sharesBefore == 0 && shares[shareholder].amount > 0) { totalStakedUsers++; } rewards[shareholder].totalExcluded = getCumulativeRewards( shares[shareholder].amount ); } function _removeShares(address shareholder, uint256 amount) private { require( shares[shareholder].amount > 0 && (amount == 0 || amount <= shares[shareholder].amount), 'you can only unstake if you have some staked' ); _distributeReward(shareholder); uint256 removeAmount = amount == 0 ? shares[shareholder].amount : amount; totalSharesDeposited -= removeAmount; shares[shareholder].amount -= removeAmount; rewards[shareholder].totalExcluded = getCumulativeRewards( shares[shareholder].amount ); } function depositRewards(uint256 _amount) external override onlyOwner { require( totalSharesDeposited > 0, 'must be shares deposited to be rewarded rewards' ); totalRewards += _amount; rewardsPerShare += (ACC_FACTOR * _amount) / totalSharesDeposited; smol.gameMint(address(this), _amount); emit DepositRewards(msg.sender, _amount); } function _distributeReward(address shareholder) internal { if (shares[shareholder].amount == 0) { return; } uint256 amount = getUnpaid(shareholder); rewards[shareholder].totalRealised += amount; rewards[shareholder].totalExcluded = getCumulativeRewards( shares[shareholder].amount ); rewards[shareholder].lastClaim = block.timestamp; if (amount > 0) { totalDistributed += amount; smol.transfer(shareholder, amount); emit DistributeReward(shareholder); } } function claimReward() external override { _distributeReward(msg.sender); emit ClaimReward(msg.sender); } // returns the unpaid rewards function getUnpaid(address shareholder) public view returns (uint256) { if (shares[shareholder].amount == 0) { return 0; } uint256 earnedRewards = getCumulativeRewards(shares[shareholder].amount); uint256 rewardsExcluded = rewards[shareholder].totalExcluded; if (earnedRewards <= rewardsExcluded) { return 0; } return earnedRewards - rewardsExcluded; } function getCumulativeRewards(uint256 share) internal view returns (uint256) { return (share * rewardsPerShare) / ACC_FACTOR; } function getShares(address user) external view override returns (uint256) { return shares[user].amount; } function getShareholderNFT() external view returns (address) { return address(shareholderNFT); } function getSmolToken() external view returns (address) { return address(smol); } function setShareholderNFT(address _nft) external onlyOwner { shareholderNFT = IERC721(_nft); } function setSmolToken(address _token) external onlyOwner { smol = ISmoltingInu(_token); } } // File contracts/SMOLNft.sol pragma solidity ^0.8.9; /** * SMOL yield bearing NFTs */ contract SMOLNft is Ownable, ERC721Burnable, ERC721Enumerable, ERC721Pausable { using Strings for uint256; using Counters for Counters.Counter; uint16 public constant PERCENT_DENOMENATOR = 1000; uint16 private constant FIVE_MINUTES = 60 * 5; Counters.Counter private _tokenIds; SMOLNftRewards private _rewards; mapping(address => bool) private _isRewardsExcluded; // user => timestamp of last mint // used for throttling wallets from minting too often mapping(address => uint256) public userLastMinted; // Base token uri string private baseTokenURI; // baseTokenURI can point to IPFS folder like https://ipfs.io/ipfs/{cid}/ while address public smol = 0x553539d40AE81FD0d9C4b991B0b77bE6f6Bc030e; uint256 public nativeCost = 9 ether / 100; // 0.09 ETH uint256 public smolCost = 100 * 10**18; uint8 public maxPerMint = 10; // Payment address address public paymentAddress = 0x98c574473313EAC3FC6af9740245949380ec166E; // Royalties address address public royaltyAddress = 0x98c574473313EAC3FC6af9740245949380ec166E; // Royalties basis points (percentage using 2 decimals - 1000 = 100, 500 = 50, 0 = 0) uint256 private royaltyBasisPoints = 50; // 5% // Token info string public constant TOKEN_NAME = 'yield bearing smolting'; string public constant TOKEN_SYMBOL = 'ybSMOL'; // yield bearing SMOL uint256 public constant TOTAL_TOKENS = 4269; // Public sale params uint256 public publicSaleStartTime; bool public publicSaleActive; bool public isRevealing; mapping(address => bool) public canMintFreeNft; mapping(address => uint256) public mintedFreeNftTimestamp; mapping(uint256 => uint256) public tokenMintedAt; mapping(uint256 => uint256) public tokenLastTransferredAt; event PublicSaleStart(uint256 indexed _saleStartTime); event PublicSalePaused(uint256 indexed _timeElapsed); event PublicSaleActive(bool indexed _publicSaleActive); event RoyaltyBasisPoints(uint256 indexed _royaltyBasisPoints); // Public sale active modifier modifier whenPublicSaleActive() { require(publicSaleActive, 'Public sale is not active'); _; } // Public sale not active modifier modifier whenPublicSaleNotActive() { require( !publicSaleActive && publicSaleStartTime == 0, 'Public sale is already active' ); _; } // Owner or public sale active modifier modifier whenOwnerOrPublicSaleActive() { require( owner() == _msgSender() || publicSaleActive, 'Public sale is not active' ); _; } // -- Constructor --// constructor(string memory _baseTokenURI) ERC721(TOKEN_NAME, TOKEN_SYMBOL) { baseTokenURI = _baseTokenURI; _rewards = new SMOLNftRewards(address(this)); _rewards.transferOwnership(_msgSender()); _isRewardsExcluded[address(this)] = true; _isRewardsExcluded[address(_rewards)] = true; } // -- External Functions -- // // Start public sale function startPublicSale() external onlyOwner whenPublicSaleNotActive { publicSaleStartTime = block.timestamp; publicSaleActive = true; emit PublicSaleStart(publicSaleStartTime); } // Set this value to the block.timestamp you'd like to reset to // Created as a way to fast foward in time for tier timing unit tests // Can also be used if needing to pause and restart public sale from original start time (returned in startPublicSale() above) function setPublicSaleStartTime(uint256 _publicSaleStartTime) external onlyOwner { publicSaleStartTime = _publicSaleStartTime; emit PublicSaleStart(publicSaleStartTime); } // Toggle public sale function togglePublicSaleActive() external onlyOwner { publicSaleActive = !publicSaleActive; emit PublicSaleActive(publicSaleActive); } // Pause public sale function pausePublicSale() external onlyOwner whenPublicSaleActive { publicSaleActive = false; emit PublicSalePaused(getElapsedSaleTime()); } // Support royalty info - See {EIP-2981}: https://eips.ethereum.org/EIPS/eip-2981 function royaltyInfo(uint256, uint256 _salePrice) external view returns (address receiver, uint256 royaltyAmount) { return ( royaltyAddress, (_salePrice * royaltyBasisPoints) / PERCENT_DENOMENATOR ); } function getElapsedSaleTime() public view returns (uint256) { return publicSaleStartTime > 0 ? block.timestamp - publicSaleStartTime : 0; } function getRewards() external view returns (address) { return address(_rewards); } // Get mints left function getMintsLeft() public view returns (uint256) { uint256 currentSupply = super.totalSupply(); return TOTAL_TOKENS - currentSupply; } // Mint token - requires tier and amount function mint(uint256 _amount) public payable whenOwnerOrPublicSaleActive { bool _isOwner = owner() == _msgSender(); require(_isOwner || getElapsedSaleTime() > 0, 'sale not active'); require( _isOwner || block.timestamp > userLastMinted[_msgSender()] + FIVE_MINUTES, 'can only mint once per 5 minutes' ); require( _amount > 0 && (_isOwner || _amount <= maxPerMint), 'must mint at least one and cannot exceed max amount' ); // Check there enough NFTs left to mint require(_amount <= getMintsLeft(), 'minting would exceed max supply'); userLastMinted[_msgSender()] = block.timestamp; // pay for NFTs & handle free NFT mint logic here as well if ( canMintFreeNft[_msgSender()] && mintedFreeNftTimestamp[_msgSender()] == 0 ) { mintedFreeNftTimestamp[_msgSender()] = block.timestamp; _payToMint(_amount - 1); } else { _payToMint(_amount); } for (uint256 i = 0; i < _amount; i++) { _tokenIds.increment(); // Safe mint _safeMint(_msgSender(), _tokenIds.current()); // Store minted at timestamp by token id tokenMintedAt[_tokenIds.current()] = block.timestamp; } } function _payToMint(uint256 _amount) internal whenOwnerOrPublicSaleActive { require(_amount > 0, 'must mint at least 1'); bool isOwner = owner() == _msgSender(); if (isOwner) { if (msg.value > 0) { Address.sendValue(payable(_msgSender()), msg.value); } return; } ISmoltingInu smolToken = ISmoltingInu(smol); uint256 totalNativeCost = nativeCost * _amount; uint256 totalSmolCost = smolCost * _amount; if (totalNativeCost > 0) { require( msg.value >= totalNativeCost, 'not enough native token provided to mint' ); uint256 balanceBefore = address(this).balance; Address.sendValue(payable(paymentAddress), totalNativeCost); // refund user for any extra native sent if (msg.value > totalNativeCost) { Address.sendValue(payable(_msgSender()), msg.value - totalNativeCost); } require( address(this).balance >= balanceBefore - msg.value, 'too much native sent' ); } else if (msg.value > 0) { Address.sendValue(payable(_msgSender()), msg.value); } if (totalSmolCost > 0) { require( smolToken.balanceOf(_msgSender()) >= totalSmolCost, 'not enough SMOL balance to mint' ); smolToken.gameBurn(_msgSender(), totalSmolCost); } } function setPaymentAddress(address _address) external onlyOwner { paymentAddress = _address; } // Set royalty wallet address function setRoyaltyAddress(address _address) external onlyOwner { royaltyAddress = _address; } function setSmolToken(address _smol) external onlyOwner { smol = _smol; } function setNativeCost(uint256 _wei) external onlyOwner { nativeCost = _wei; } function setSmolCost(uint256 _numTokens) external onlyOwner { smolCost = _numTokens; } // Set royalty basis points function setRoyaltyBasisPoints(uint256 _basisPoints) external onlyOwner { royaltyBasisPoints = _basisPoints; emit RoyaltyBasisPoints(_basisPoints); } // Set base URI function setBaseURI(string memory _uri) external onlyOwner { baseTokenURI = _uri; } function setRewards(address _contract) external onlyOwner { _rewards = SMOLNftRewards(_contract); } function setIsRewardsExcluded(address _wallet, bool _isExcluded) public onlyOwner { _isRewardsExcluded[_wallet] = _isExcluded; if (_isExcluded) { _rewards.setShare(_wallet, 0); } else { _rewards.setShare(_wallet, balanceOf(_wallet)); } } function setMaxPerMint(uint8 _max) external onlyOwner { require(maxPerMint > 0, 'have to be able to mint at least 1 NFT'); maxPerMint = _max; } function setCanMintFreeNft(address _wallet, bool _canMintFree) external onlyOwner { canMintFreeNft[_wallet] = _canMintFree; } function setCanMintFreeNftBulk(address[] memory _wallets, bool _canMintFree) external onlyOwner { for (uint256 i = 0; i < _wallets.length; i++) { canMintFreeNft[_wallets[i]] = _canMintFree; } } function isRewardsExcluded(address _wallet) external view returns (bool) { return _isRewardsExcluded[_wallet]; } function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) { require(_exists(_tokenId), 'Nonexistent token'); return string(abi.encodePacked(_baseURI(), _tokenId.toString(), '.json')); } function isMinted(uint256 _tokenId) external view returns (bool) { return _exists(_tokenId); } // Contract metadata URI - Support for OpenSea: https://docs.opensea.io/docs/contract-level-metadata function contractURI() public view returns (string memory) { return string(abi.encodePacked(_baseURI(), 'contract.json')); } // Override supportsInterface - See {IERC165-supportsInterface} function supportsInterface(bytes4 _interfaceId) public view virtual override(ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(_interfaceId); } // Pauses all token transfers - See {ERC721Pausable} function pause() public virtual onlyOwner { _pause(); } // Unpauses all token transfers - See {ERC721Pausable} function unpause() public virtual onlyOwner { _unpause(); } function reveal() external onlyOwner { require(!isRevealing, 'already revealing'); isRevealing = true; } //-- Internal Functions --// function _setRewardsShares(address _from, address _to) internal { if (!_isRewardsExcluded[_from] && _from != address(0)) { _rewards.setShare(_from, balanceOf(_from)); } if (!_isRewardsExcluded[_to] && _to != address(0)) { _rewards.setShare(_to, balanceOf(_to)); } } // Get base URI function _baseURI() internal view override returns (string memory) { return baseTokenURI; } // before all token transfer function _beforeTokenTransfer( address _from, address _to, uint256 _tokenId ) internal virtual override(ERC721, ERC721Enumerable, ERC721Pausable) { // Store token last transfer timestamp by id tokenLastTransferredAt[_tokenId] = block.timestamp; super._beforeTokenTransfer(_from, _to, _tokenId); } // after all token transfer function _afterTokenTransfer( address _from, address _to, uint256 _tokenId ) internal virtual override(ERC721) { _setRewardsShares(_from, _to); super._afterTokenTransfer(_from, _to, _tokenId); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_shareholderNFT","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"ClaimReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountTokens","type":"uint256"}],"name":"DepositRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"DistributeReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"claimReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getShareholderNFT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSmolToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"shareholder","type":"address"}],"name":"getUnpaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"totalExcluded","type":"uint256"},{"internalType":"uint256","name":"totalRealised","type":"uint256"},{"internalType":"uint256","name":"lastClaim","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"shareholder","type":"address"},{"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"setShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nft","type":"address"}],"name":"setShareholderNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"setSmolToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalDistributed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSharesDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakedUsers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052600280546001600160a01b03191673553539d40ae81fd0d9c4b991b0b77be6f6bc030e17905534801561003657600080fd5b50604051610e6b380380610e6b833981016040819052610055916100d3565b61005e33610083565b600180546001600160a01b0319166001600160a01b0392909216919091179055610103565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156100e557600080fd5b81516001600160a01b03811681146100fc57600080fd5b9392505050565b610d59806101126000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638bdf67f2116100a2578063e262391811610071578063e262391814610230578063efca2eed14610243578063f04da65b1461024c578063f2fde38b14610275578063f81ca2581461028857600080fd5b80638bdf67f2146101fb5780638da5cb5b1461020e578063b88a802f1461021f578063c7e1d0b11461022757600080fd5b80633c6e6789116100e95780633c6e6789146101bb5780635b00cfcb146101c4578063715018a6146101d757806380bb4055146101df57806389d96917146101e857600080fd5b80630700037d1461011b578063097046041461016a5780630e15561a1461018f57806314b6ca96146101a6575b600080fd5b61014a610129366004610bc6565b60066020526000908152604090208054600182015460029092015490919083565b604080519384526020840192909252908201526060015b60405180910390f35b6001546001600160a01b03165b6040516001600160a01b039091168152602001610161565b61019860075481565b604051908152602001610161565b6101b96101b4366004610be8565b610299565b005b61019860045481565b6101b96101d2366004610bc6565b610392565b6101b96103de565b61019860035481565b6101986101f6366004610bc6565b610414565b6101b9610209366004610c12565b61049a565b6000546001600160a01b0316610177565b6101b961061d565b61019860095481565b6101b961023e366004610bc6565b61065b565b61019860085481565b61019861025a366004610bc6565b6001600160a01b031660009081526005602052604090205490565b6101b9610283366004610bc6565b6106a7565b6002546001600160a01b0316610177565b6001546001600160a01b031633146102f15760405162461bcd60e51b81526020600482015260166024820152751b5d5cdd081899481d1bdad95b8818dbdb9d1c9858dd60521b60448201526064015b60405180910390fd5b6001600160a01b038216600090815260056020526040902054811015610344576001600160a01b03821660009081526005602052604090205461034090839061033b908490610c41565b610742565b5050565b6001600160a01b038216600090815260056020526040902054811115610340576001600160a01b03821660009081526005602052604090205461034090839061038d9084610c41565b6108a4565b6000546001600160a01b031633146103bc5760405162461bcd60e51b81526004016102e890610c58565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146104085760405162461bcd60e51b81526004016102e890610c58565b61041260006109aa565b565b6001600160a01b03811660009081526005602052604081205461043957506000919050565b6001600160a01b03821660009081526005602052604081205461045b906109fa565b6001600160a01b038416600090815260066020526040902054909150808211610488575060009392505050565b6104928183610c41565b949350505050565b6000546001600160a01b031633146104c45760405162461bcd60e51b81526004016102e890610c58565b60006004541161052e5760405162461bcd60e51b815260206004820152602f60248201527f6d75737420626520736861726573206465706f736974656420746f206265207260448201526e65776172646564207265776172647360881b60648201526084016102e8565b80600760008282546105409190610c8d565b9091555050600454610561826ec097ce7bc90715b34b9f1000000000610ca5565b61056b9190610cc4565b6009600082825461057c9190610c8d565b9091555050600254604051634eb9029960e01b8152306004820152602481018390526001600160a01b0390911690634eb9029990604401600060405180830381600087803b1580156105cd57600080fd5b505af11580156105e1573d6000803e3d6000fd5b50506040518381523392507fb9ad861b752f80117b35bea6dec99933d8a5ae360f2839ee8784b750d5613409915060200160405180910390a250565b61062633610a2a565b6040513381527f63e32091e4445d16e29c33a6b264577c2d86694021aa4e6f4dd590048f5792e89060200160405180910390a1565b6000546001600160a01b031633146106855760405162461bcd60e51b81526004016102e890610c58565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146106d15760405162461bcd60e51b81526004016102e890610c58565b6001600160a01b0381166107365760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016102e8565b61073f816109aa565b50565b6001600160a01b03821660009081526005602052604090205415801590610789575080158061078957506001600160a01b0382166000908152600560205260409020548111155b6107ea5760405162461bcd60e51b815260206004820152602c60248201527f796f752063616e206f6e6c7920756e7374616b6520696620796f75206861766560448201526b081cdbdb59481cdd185ad95960a21b60648201526084016102e8565b6107f382610a2a565b60008115610801578161081b565b6001600160a01b0383166000908152600560205260409020545b9050806004600082825461082f9190610c41565b90915550506001600160a01b0383166000908152600560205260408120805483929061085c908490610c41565b90915550506001600160a01b038316600090815260056020526040902054610883906109fa565b6001600160a01b039093166000908152600660205260409020929092555050565b6001600160a01b038216600090815260056020526040902054156108cb576108cb82610a2a565b6001600160a01b03821660009081526005602052604081205460048054919284926108f7908490610c8d565b90915550506001600160a01b03831660009081526005602052604081208054849290610924908490610c8d565b90915550506001600160a01b0383166000908152600560205260409020426001909101558015801561096d57506001600160a01b03831660009081526005602052604090205415155b15610988576003805490600061098283610ce6565b91905055505b6001600160a01b038316600090815260056020526040902054610883906109fa565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006ec097ce7bc90715b34b9f100000000060095483610a1a9190610ca5565b610a249190610cc4565b92915050565b6001600160a01b038116600090815260056020526040902054610a4a5750565b6000610a5582610414565b6001600160a01b038316600090815260066020526040812060010180549293508392909190610a85908490610c8d565b90915550506001600160a01b038216600090815260056020526040902054610aac906109fa565b6001600160a01b0383166000908152600660205260409020908155426002909101558015610340578060086000828254610ae69190610c8d565b909155505060025460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb90604401602060405180830381600087803b158015610b3957600080fd5b505af1158015610b4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b719190610d01565b506040516001600160a01b038316907f12aec06443e8d0b9713948f69d526f256f435e4d689c9d5215a1387d4230597d90600090a25050565b80356001600160a01b0381168114610bc157600080fd5b919050565b600060208284031215610bd857600080fd5b610be182610baa565b9392505050565b60008060408385031215610bfb57600080fd5b610c0483610baa565b946020939093013593505050565b600060208284031215610c2457600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b600082821015610c5357610c53610c2b565b500390565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60008219821115610ca057610ca0610c2b565b500190565b6000816000190483118215151615610cbf57610cbf610c2b565b500290565b600082610ce157634e487b7160e01b600052601260045260246000fd5b500490565b6000600019821415610cfa57610cfa610c2b565b5060010190565b600060208284031215610d1357600080fd5b81518015158114610be157600080fdfea26469706673582212207429bfa39e98459cef3f03e1be0a2edd311bb258139eaf9bdf6715473fb33cda64736f6c63430008090033000000000000000000000000d3f5bbec94c5b16b68ada1721bbd7a9d6af8cc27
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638bdf67f2116100a2578063e262391811610071578063e262391814610230578063efca2eed14610243578063f04da65b1461024c578063f2fde38b14610275578063f81ca2581461028857600080fd5b80638bdf67f2146101fb5780638da5cb5b1461020e578063b88a802f1461021f578063c7e1d0b11461022757600080fd5b80633c6e6789116100e95780633c6e6789146101bb5780635b00cfcb146101c4578063715018a6146101d757806380bb4055146101df57806389d96917146101e857600080fd5b80630700037d1461011b578063097046041461016a5780630e15561a1461018f57806314b6ca96146101a6575b600080fd5b61014a610129366004610bc6565b60066020526000908152604090208054600182015460029092015490919083565b604080519384526020840192909252908201526060015b60405180910390f35b6001546001600160a01b03165b6040516001600160a01b039091168152602001610161565b61019860075481565b604051908152602001610161565b6101b96101b4366004610be8565b610299565b005b61019860045481565b6101b96101d2366004610bc6565b610392565b6101b96103de565b61019860035481565b6101986101f6366004610bc6565b610414565b6101b9610209366004610c12565b61049a565b6000546001600160a01b0316610177565b6101b961061d565b61019860095481565b6101b961023e366004610bc6565b61065b565b61019860085481565b61019861025a366004610bc6565b6001600160a01b031660009081526005602052604090205490565b6101b9610283366004610bc6565b6106a7565b6002546001600160a01b0316610177565b6001546001600160a01b031633146102f15760405162461bcd60e51b81526020600482015260166024820152751b5d5cdd081899481d1bdad95b8818dbdb9d1c9858dd60521b60448201526064015b60405180910390fd5b6001600160a01b038216600090815260056020526040902054811015610344576001600160a01b03821660009081526005602052604090205461034090839061033b908490610c41565b610742565b5050565b6001600160a01b038216600090815260056020526040902054811115610340576001600160a01b03821660009081526005602052604090205461034090839061038d9084610c41565b6108a4565b6000546001600160a01b031633146103bc5760405162461bcd60e51b81526004016102e890610c58565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146104085760405162461bcd60e51b81526004016102e890610c58565b61041260006109aa565b565b6001600160a01b03811660009081526005602052604081205461043957506000919050565b6001600160a01b03821660009081526005602052604081205461045b906109fa565b6001600160a01b038416600090815260066020526040902054909150808211610488575060009392505050565b6104928183610c41565b949350505050565b6000546001600160a01b031633146104c45760405162461bcd60e51b81526004016102e890610c58565b60006004541161052e5760405162461bcd60e51b815260206004820152602f60248201527f6d75737420626520736861726573206465706f736974656420746f206265207260448201526e65776172646564207265776172647360881b60648201526084016102e8565b80600760008282546105409190610c8d565b9091555050600454610561826ec097ce7bc90715b34b9f1000000000610ca5565b61056b9190610cc4565b6009600082825461057c9190610c8d565b9091555050600254604051634eb9029960e01b8152306004820152602481018390526001600160a01b0390911690634eb9029990604401600060405180830381600087803b1580156105cd57600080fd5b505af11580156105e1573d6000803e3d6000fd5b50506040518381523392507fb9ad861b752f80117b35bea6dec99933d8a5ae360f2839ee8784b750d5613409915060200160405180910390a250565b61062633610a2a565b6040513381527f63e32091e4445d16e29c33a6b264577c2d86694021aa4e6f4dd590048f5792e89060200160405180910390a1565b6000546001600160a01b031633146106855760405162461bcd60e51b81526004016102e890610c58565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146106d15760405162461bcd60e51b81526004016102e890610c58565b6001600160a01b0381166107365760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016102e8565b61073f816109aa565b50565b6001600160a01b03821660009081526005602052604090205415801590610789575080158061078957506001600160a01b0382166000908152600560205260409020548111155b6107ea5760405162461bcd60e51b815260206004820152602c60248201527f796f752063616e206f6e6c7920756e7374616b6520696620796f75206861766560448201526b081cdbdb59481cdd185ad95960a21b60648201526084016102e8565b6107f382610a2a565b60008115610801578161081b565b6001600160a01b0383166000908152600560205260409020545b9050806004600082825461082f9190610c41565b90915550506001600160a01b0383166000908152600560205260408120805483929061085c908490610c41565b90915550506001600160a01b038316600090815260056020526040902054610883906109fa565b6001600160a01b039093166000908152600660205260409020929092555050565b6001600160a01b038216600090815260056020526040902054156108cb576108cb82610a2a565b6001600160a01b03821660009081526005602052604081205460048054919284926108f7908490610c8d565b90915550506001600160a01b03831660009081526005602052604081208054849290610924908490610c8d565b90915550506001600160a01b0383166000908152600560205260409020426001909101558015801561096d57506001600160a01b03831660009081526005602052604090205415155b15610988576003805490600061098283610ce6565b91905055505b6001600160a01b038316600090815260056020526040902054610883906109fa565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006ec097ce7bc90715b34b9f100000000060095483610a1a9190610ca5565b610a249190610cc4565b92915050565b6001600160a01b038116600090815260056020526040902054610a4a5750565b6000610a5582610414565b6001600160a01b038316600090815260066020526040812060010180549293508392909190610a85908490610c8d565b90915550506001600160a01b038216600090815260056020526040902054610aac906109fa565b6001600160a01b0383166000908152600660205260409020908155426002909101558015610340578060086000828254610ae69190610c8d565b909155505060025460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb90604401602060405180830381600087803b158015610b3957600080fd5b505af1158015610b4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b719190610d01565b506040516001600160a01b038316907f12aec06443e8d0b9713948f69d526f256f435e4d689c9d5215a1387d4230597d90600090a25050565b80356001600160a01b0381168114610bc157600080fd5b919050565b600060208284031215610bd857600080fd5b610be182610baa565b9392505050565b60008060408385031215610bfb57600080fd5b610c0483610baa565b946020939093013593505050565b600060208284031215610c2457600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b600082821015610c5357610c53610c2b565b500390565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60008219821115610ca057610ca0610c2b565b500190565b6000816000190483118215151615610cbf57610cbf610c2b565b500290565b600082610ce157634e487b7160e01b600052601260045260246000fd5b500490565b6000600019821415610cfa57610cfa610c2b565b5060010190565b600060208284031215610d1357600080fd5b81518015158114610be157600080fdfea26469706673582212207429bfa39e98459cef3f03e1be0a2edd311bb258139eaf9bdf6715473fb33cda64736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d3f5bbec94c5b16b68ada1721bbd7a9d6af8cc27
-----Decoded View---------------
Arg [0] : _shareholderNFT (address): 0xd3F5bBeC94C5B16B68aDa1721BBD7A9d6Af8cC27
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d3f5bbec94c5b16b68ada1721bbd7a9d6af8cc27
Deployed Bytecode Sourcemap
52810:5128:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53467:41;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;585:25:1;;;641:2;626:18;;619:34;;;;669:18;;;662:34;573:2;558:18;53467:41:0;;;;;;;;57524:104;57607:14;;-1:-1:-1;;;;;57607:14:0;57524:104;;;-1:-1:-1;;;;;871:32:1;;;853:51;;841:2;826:18;57524:104:0;707:203:1;53515:27:0;;;;;;;;;1061:25:1;;;1049:2;1034:18;53515:27:0;915:177:1;54044:562:0;;;;;;:::i;:::-;;:::i;:::-;;53234:35;;;;;;57838:97;;;;;;:::i;:::-;;:::i;46877:::-;;;:::i;53198:31::-;;;;;;56850:408;;;;;;:::i;:::-;;:::i;55756:381::-;;;;;;:::i;:::-;;:::i;46266:81::-;46312:7;46335:6;-1:-1:-1;;;;;46335:6:0;46266:81;;56693:118;;;:::i;53583:30::-;;;;;;57729:103;;;;;;:::i;:::-;;:::i;53547:31::-;;;;;;57405:113;;;;;;:::i;:::-;-1:-1:-1;;;;;57493:12:0;57470:7;57493:12;;;:6;:12;;;;;:19;;57405:113;47119:191;;;;;;:::i;:::-;;:::i;57634:89::-;57712:4;;-1:-1:-1;;;;;57712:4:0;57634:89;;54044:562;53885:14;;-1:-1:-1;;;;;53885:14:0;53863:10;:37;53855:72;;;;-1:-1:-1;;;53855:72:0;;1743:2:1;53855:72:0;;;1725:21:1;1782:2;1762:18;;;1755:30;-1:-1:-1;;;1801:18:1;;;1794:52;1863:18;;53855:72:0;;;;;;;;;-1:-1:-1;;;;;54344:19:0;::::1;;::::0;;;:6:::1;:19;::::0;;;;:26;:39;-1:-1:-1;54340:261:0::1;;;-1:-1:-1::0;;;;;54421:19:0;::::1;;::::0;;;:6:::1;:19;::::0;;;;:26;54394:67:::1;::::0;54408:11;;54421:39:::1;::::0;54450:10;;54421:39:::1;:::i;:::-;54394:13;:67::i;:::-;54044:562:::0;;:::o;54340:261::-:1;-1:-1:-1::0;;;;;54479:19:0;::::1;;::::0;;;:6:::1;:19;::::0;;;;:26;:39;-1:-1:-1;54475:126:0::1;;;-1:-1:-1::0;;;;;54566:19:0;::::1;;::::0;;;:6:::1;:19;::::0;;;;:26;54529:64:::1;::::0;54540:11;;54553:39:::1;::::0;:10;:39:::1;:::i;:::-;54529:10;:64::i;57838:97::-:0;46312:7;46335:6;-1:-1:-1;;;;;46335:6:0;16405:10;46468:23;46460:68;;;;-1:-1:-1;;;46460:68:0;;;;;;;:::i;:::-;57902:4:::1;:27:::0;;-1:-1:-1;;;;;;57902:27:0::1;-1:-1:-1::0;;;;;57902:27:0;;;::::1;::::0;;;::::1;::::0;;57838:97::o;46877:::-;46312:7;46335:6;-1:-1:-1;;;;;46335:6:0;16405:10;46468:23;46460:68;;;;-1:-1:-1;;;46460:68:0;;;;;;;:::i;:::-;46938:30:::1;46965:1;46938:18;:30::i;:::-;46877:97::o:0;56850:408::-;-1:-1:-1;;;;;56931:19:0;;56911:7;56931:19;;;:6;:19;;;;;:26;56927:62;;-1:-1:-1;56980:1:0;;56850:408;-1:-1:-1;56850:408:0:o;56927:62::-;-1:-1:-1;;;;;57042:19:0;;56997:21;57042:19;;;:6;:19;;;;;:26;57021:48;;:20;:48::i;:::-;-1:-1:-1;;;;;57102:20:0;;57076:23;57102:20;;;:7;:20;;;;;:34;56997:72;;-1:-1:-1;57147:32:0;;;57143:63;;-1:-1:-1;57197:1:0;;56850:408;-1:-1:-1;;;56850:408:0:o;57143:63::-;57221:31;57237:15;57221:13;:31;:::i;:::-;57214:38;56850:408;-1:-1:-1;;;;56850:408:0:o;55756:381::-;46312:7;46335:6;-1:-1:-1;;;;;46335:6:0;16405:10;46468:23;46460:68;;;;-1:-1:-1;;;46460:68:0;;;;;;;:::i;:::-;55871:1:::1;55848:20;;:24;55832:105;;;::::0;-1:-1:-1;;;55832:105:0;;2717:2:1;55832:105:0::1;::::0;::::1;2699:21:1::0;2756:2;2736:18;;;2729:30;2795:34;2775:18;;;2768:62;-1:-1:-1;;;2846:18:1;;;2839:45;2901:19;;55832:105:0::1;2515:411:1::0;55832:105:0::1;55962:7;55946:12;;:23;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;56020:20:0::1;::::0;55996::::1;56009:7:::0;53658:6:::1;55996:20;:::i;:::-;55995:45;;;;:::i;:::-;55976:15;;:64;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;56047:4:0::1;::::0;:37:::1;::::0;-1:-1:-1;;;56047:37:0;;56069:4:::1;56047:37;::::0;::::1;3633:51:1::0;3700:18;;;3693:34;;;-1:-1:-1;;;;;56047:4:0;;::::1;::::0;:13:::1;::::0;3606:18:1;;56047:37:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;56096:35:0::1;::::0;1061:25:1;;;56111:10:0::1;::::0;-1:-1:-1;56096:35:0::1;::::0;-1:-1:-1;1049:2:1;1034:18;56096:35:0::1;;;;;;;55756:381:::0;:::o;56693:118::-;56741:29;56759:10;56741:17;:29::i;:::-;56782:23;;56794:10;853:51:1;;56782:23:0;;841:2:1;826:18;56782:23:0;;;;;;;56693:118::o;57729:103::-;46312:7;46335:6;-1:-1:-1;;;;;46335:6:0;16405:10;46468:23;46460:68;;;;-1:-1:-1;;;46460:68:0;;;;;;;:::i;:::-;57796:14:::1;:30:::0;;-1:-1:-1;;;;;;57796:30:0::1;-1:-1:-1::0;;;;;57796:30:0;;;::::1;::::0;;;::::1;::::0;;57729:103::o;47119:191::-;46312:7;46335:6;-1:-1:-1;;;;;46335:6:0;16405:10;46468:23;46460:68;;;;-1:-1:-1;;;46460:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;47204:22:0;::::1;47196:73;;;::::0;-1:-1:-1;;;47196:73:0;;3940:2:1;47196:73:0::1;::::0;::::1;3922:21:1::0;3979:2;3959:18;;;3952:30;4018:34;3998:18;;;3991:62;-1:-1:-1;;;4069:18:1;;;4062:36;4115:19;;47196:73:0::1;3738:402:1::0;47196:73:0::1;47276:28;47295:8;47276:18;:28::i;:::-;47119:191:::0;:::o;55177:573::-;-1:-1:-1;;;;;55268:19:0;;55297:1;55268:19;;;:6;:19;;;;;:26;:30;;;;:96;;-1:-1:-1;55312:11:0;;;:51;;-1:-1:-1;;;;;;55337:19:0;;;;;;:6;:19;;;;;:26;55327:36;;;55312:51;55252:174;;;;-1:-1:-1;;;55252:174:0;;4347:2:1;55252:174:0;;;4329:21:1;4386:2;4366:18;;;4359:30;4425:34;4405:18;;;4398:62;-1:-1:-1;;;4476:18:1;;;4469:42;4528:19;;55252:174:0;4145:408:1;55252:174:0;55433:30;55451:11;55433:17;:30::i;:::-;55472:20;55495:11;;:49;;55538:6;55495:49;;;-1:-1:-1;;;;;55509:19:0;;;;;;:6;:19;;;;;:26;55495:49;55472:72;;55577:12;55553:20;;:36;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;55596:19:0;;;;;;:6;:19;;;;;:42;;55626:12;;55596:19;:42;;55626:12;;55596:42;:::i;:::-;;;;-1:-1:-1;;;;;;;55711:19:0;;;;;;:6;:19;;;;;:26;55682:62;;:20;:62::i;:::-;-1:-1:-1;;;;;55645:20:0;;;;;;;:7;:20;;;;;:99;;;;-1:-1:-1;;55177:573:0:o;54612:559::-;-1:-1:-1;;;;;54688:19:0;;54717:1;54688:19;;;:6;:19;;;;;:26;:30;54684:83;;54729:30;54747:11;54729:17;:30::i;:::-;-1:-1:-1;;;;;54798:19:0;;54775:20;54798:19;;;:6;:19;;;;;:26;54833:20;:30;;54798:26;;54857:6;;54833:30;;54857:6;;54833:30;:::i;:::-;;;;-1:-1:-1;;;;;;;54870:19:0;;;;;;:6;:19;;;;;:36;;54900:6;;54870:19;:36;;54900:6;;54870:36;:::i;:::-;;;;-1:-1:-1;;;;;;;54913:19:0;;;;;;:6;:19;;;;;54946:15;54913:30;;;;:48;54972:17;;:51;;;;-1:-1:-1;;;;;;54993:19:0;;55022:1;54993:19;;;:6;:19;;;;;:26;:30;;54972:51;54968:92;;;55034:16;:18;;;:16;:18;;;:::i;:::-;;;;;;54968:92;-1:-1:-1;;;;;55132:19:0;;;;;;:6;:19;;;;;:26;55103:62;;:20;:62::i;47460:177::-;47530:16;47549:6;;-1:-1:-1;;;;;47562:17:0;;;-1:-1:-1;;;;;;47562:17:0;;;;;;47591:40;;47549:6;;;;;;;47591:40;;47530:16;47591:40;47523:114;47460:177;:::o;57264:135::-;57332:7;53658:6;57364:15;;57356:5;:23;;;;:::i;:::-;57355:38;;;;:::i;:::-;57348:45;57264:135;-1:-1:-1;;57264:135:0:o;56143:544::-;-1:-1:-1;;;;;56211:19:0;;;;;;:6;:19;;;;;:26;56207:60;;56143:544;:::o;56207:60::-;56275:14;56292:22;56302:11;56292:9;:22::i;:::-;-1:-1:-1;;;;;56323:20:0;;;;;;:7;:20;;;;;:34;;:44;;56275:39;;-1:-1:-1;56275:39:0;;56323:34;;:20;:44;;56275:39;;56323:44;:::i;:::-;;;;-1:-1:-1;;;;;;;56440:19:0;;;;;;:6;:19;;;;;:26;56411:62;;:20;:62::i;:::-;-1:-1:-1;;;;;56374:20:0;;;;;;:7;:20;;;;;:99;;;56513:15;56480:30;;;;:48;56541:10;;56537:145;;56582:6;56562:16;;:26;;;;;;;:::i;:::-;;;;-1:-1:-1;;56597:4:0;;:34;;-1:-1:-1;;;56597:34:0;;-1:-1:-1;;;;;3651:32:1;;;56597:34:0;;;3633:51:1;3700:18;;;3693:34;;;56597:4:0;;;;:13;;3606:18:1;;56597:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;56645:29:0;;-1:-1:-1;;;;;56645:29:0;;;;;;;;56200:487;56143:544;:::o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:186::-;251:6;304:2;292:9;283:7;279:23;275:32;272:52;;;320:1;317;310:12;272:52;343:29;362:9;343:29;:::i;:::-;333:39;192:186;-1:-1:-1;;;192:186:1:o;1097:254::-;1165:6;1173;1226:2;1214:9;1205:7;1201:23;1197:32;1194:52;;;1242:1;1239;1232:12;1194:52;1265:29;1284:9;1265:29;:::i;:::-;1255:39;1341:2;1326:18;;;;1313:32;;-1:-1:-1;;;1097:254:1:o;1356:180::-;1415:6;1468:2;1456:9;1447:7;1443:23;1439:32;1436:52;;;1484:1;1481;1474:12;1436:52;-1:-1:-1;1507:23:1;;1356:180;-1:-1:-1;1356:180:1:o;1892:127::-;1953:10;1948:3;1944:20;1941:1;1934:31;1984:4;1981:1;1974:15;2008:4;2005:1;1998:15;2024:125;2064:4;2092:1;2089;2086:8;2083:34;;;2097:18;;:::i;:::-;-1:-1:-1;2134:9:1;;2024:125::o;2154:356::-;2356:2;2338:21;;;2375:18;;;2368:30;2434:34;2429:2;2414:18;;2407:62;2501:2;2486:18;;2154:356::o;2931:128::-;2971:3;3002:1;2998:6;2995:1;2992:13;2989:39;;;3008:18;;:::i;:::-;-1:-1:-1;3044:9:1;;2931:128::o;3064:168::-;3104:7;3170:1;3166;3162:6;3158:14;3155:1;3152:21;3147:1;3140:9;3133:17;3129:45;3126:71;;;3177:18;;:::i;:::-;-1:-1:-1;3217:9:1;;3064:168::o;3237:217::-;3277:1;3303;3293:132;;3347:10;3342:3;3338:20;3335:1;3328:31;3382:4;3379:1;3372:15;3410:4;3407:1;3400:15;3293:132;-1:-1:-1;3439:9:1;;3237:217::o;4558:135::-;4597:3;-1:-1:-1;;4618:17:1;;4615:43;;;4638:18;;:::i;:::-;-1:-1:-1;4685:1:1;4674:13;;4558:135::o;4698:277::-;4765:6;4818:2;4806:9;4797:7;4793:23;4789:32;4786:52;;;4834:1;4831;4824:12;4786:52;4866:9;4860:16;4919:5;4912:13;4905:21;4898:5;4895:32;4885:60;;4941:1;4938;4931:12
Swarm Source
ipfs://7429bfa39e98459cef3f03e1be0a2edd311bb258139eaf9bdf6715473fb33cda
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.