ERC-1155
Overview
Max Total Supply
389
Holders
87
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Source Code Verified (Exact Match)
Contract Name:
PlayerHousing
Compiler Version
v0.8.14+commit.80d49f37
Optimization Enabled:
Yes with 10000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.14; import "openzeppelin/access/Ownable.sol"; import "openzeppelin/utils/Strings.sol"; import "./ERC1155B.sol"; import "./ILockManager.sol"; import "./ITickets.sol"; /// @title Solarbots Player Housing /// @author Solarbots (https://solarbots.io) contract PlayerHousing is ERC1155B, Ownable { // ---------- CONSTANTS ---------- /// @notice Maximum amount of tokens that can be minted per faction /// Arboria tokens use IDs 0-5999, Illskagaard tokens use IDs 6000-11999, /// and Lacrean Empire tokens use IDs 12000-17999 for a total of 18000 tokens uint256 public constant MAX_SUPPLY_PER_FACTION = 6000; /// @notice Illskagaard tokens use IDs 6000-11999 uint256 public constant ID_OFFSET_ILLSKAGAARD = 6000; /// @notice Lacrean Empire tokens use IDs 12000-17999 uint256 public constant ID_OFFSET_LACREAN = 12000; /// @notice Maximum amount of tokens that can be minted per transaction uint256 public constant MAX_MINT_AMOUNT_PER_TX = 5; /// @notice Price to mint one token uint256 public constant MINT_PRICE = 0.1 ether; /// @notice Token ID of whitelist ticket in tickets contract uint256 public constant WHITELIST_TICKET_ID = 0; /// @notice FOA rewards emitted per second per token /// @dev 600_000_000e18 / 18_000 / 10 / 365 / 24 / 60 / 60 uint256 public constant REWARDS_PER_SECOND = 105699306612548; string public constant ERROR_NO_CONTRACT_MINTING = "PlayerHousing: No contract minting"; string public constant ERROR_NO_METADATA = "PlayerHousing: No metadata"; string public constant ERROR_NOT_APPROVED_FOR_REWARDS = "PlayerHousing: Not approved for rewards"; string public constant ERROR_OVER_MAX_AMOUNT_PER_TX_ARBORIA = "PlayerHousing: Arboria over max amount per tx"; string public constant ERROR_OVER_MAX_AMOUNT_PER_TX_ILLSKAGAARD = "PlayerHousing: Illskagaard over max amount per tx"; string public constant ERROR_OVER_MAX_AMOUNT_PER_TX_LACREAN = "PlayerHousing: Lacrean Empire over max amount per tx"; string public constant ERROR_OVER_MAX_AMOUNT_PER_TX_TOTAL = "PlayerHousing: Total over max amount per tx"; string public constant ERROR_REACHED_MAX_SUPPLY_ARBORIA = "PlayerHousing: Reached max Arboria supply"; string public constant ERROR_REACHED_MAX_SUPPLY_ILLSKAGAARD = "PlayerHousing: Reached max Illskagaard supply"; string public constant ERROR_REACHED_MAX_SUPPLY_LACREAN = "PlayerHousing: Reached max Lacrean Empire supply"; string public constant ERROR_SALE_NOT_READY_WHITELIST = "PlayerHousing: Whitelist sale not ready"; string public constant ERROR_SALE_NOT_READY_PUBLIC = "PlayerHousing: Public sale not ready"; string public constant ERROR_TOKEN_LOCKED = "PlayerHousing: Token locked"; string public constant ERROR_TOTAL_AMOUNT_BELOW_TWO = "PlayerHousing: Total amount below 2"; string public constant ERROR_WRONG_PRICE = "PlayerHousing: Wrong price"; /// @notice End of FOA rewards emittance uint256 public immutable TIMESTAMP_REWARDS_END; /// @notice Start of whitelist sale uint256 public immutable TIMESTAMP_SALE_WHITELIST; /// @notice Start of public sale uint256 public immutable TIMESTAMP_SALE_PUBLIC; /// @notice Tickets contract /// @custom:security non-reentrant ITickets public immutable TICKETS; uint256 private constant _BITSHIFT_TOTAL_SUPPLY_ILLSKAGAARD = 16; uint256 private constant _BITSHIFT_TOTAL_SUPPLY_LACREAN = 32; uint256 private constant _BITSHIFT_REWARDS_LAST_UPDATED = 16; uint256 private constant _BITSHIFT_REWARDS_BALANCE = 48; uint256 private constant _BITMASK_TOTAL_SUPPLY = type(uint16).max; uint256 private constant _BITMASK_TOTAL_SUPPLY_ARBORIA = ~_BITMASK_TOTAL_SUPPLY; uint256 private constant _BITMASK_TOTAL_SUPPLY_ILLSKAGAARD = ~(_BITMASK_TOTAL_SUPPLY << _BITSHIFT_TOTAL_SUPPLY_ILLSKAGAARD); uint256 private constant _BITMASK_TOTAL_SUPPLY_LACREAN = ~(_BITMASK_TOTAL_SUPPLY << _BITSHIFT_TOTAL_SUPPLY_LACREAN); uint256 private constant _BITMASK_REWARDS_TOKEN_BALANCE = type(uint16).max; uint256 private constant _BITMASK_REWARDS_LAST_UPDATED = type(uint32).max; // ---------- STATE ---------- /// @notice Contains rewards balance, token balance, and timestamp of last rewards update for each token owner /// @dev Bit Layout: /// [0-15] Token balance - `tokenBalance` /// [16-47] Timestamp of last rewards update - `lastUpdated` /// [48-255] Rewards balance - `rewardsBalance` mapping(address => uint256) public rewardsBitField; /// @notice Approved addresses have write access to `rewardsBitField` /// @custom:security write-protection="onlyOwner()" mapping(address => bool) public isApprovedForRewards; /// @notice Lock manager contract /// @custom:security non-reentrant /// @custom:security write-protection="onlyOwner()" ILockManager public lockManager; /// @notice Metadata base URI /// @custom:security write-protection="onlyOwner()" string public baseURI; /// @notice Metadata URI suffix /// @custom:security write-protection="onlyOwner()" string public uriSuffix; /// @notice Contains total supply of each faction /// @dev Bit Layout: /// [0-15] Total supply of Arboria tokens - `totalSupplyArboria` /// [16-31] Total supply of Illskagard tokens - `totalSupplyIllskagard` /// [32-47] Total supply of Lacrean Empire tokens - `totalSupplyLacrean` uint256 private _totalSupplyBitField; // ---------- EVENTS ---------- event ApprovalForRewards(address indexed operator, bool approved); event LockManagerTransfer(address indexed previousLockManager, address indexed newLockManager); // ---------- CONSTRUCTOR ---------- /// @param owner Contract owner /// @param timestampSaleWhitelist Start of whitelist sale /// @param timestampSalePublic Start of public sale /// @param timestampRewardsEnd End of FOA rewards emittance /// @param tickets Address of tickets contract /// @param _lockManager Address of lock manager contract // slither-disable-next-line protected-vars constructor( address owner, uint256 timestampSaleWhitelist, uint256 timestampSalePublic, uint256 timestampRewardsEnd, address tickets, address _lockManager ) { _transferOwnership(owner); TIMESTAMP_SALE_WHITELIST = timestampSaleWhitelist; TIMESTAMP_SALE_PUBLIC = timestampSalePublic; TIMESTAMP_REWARDS_END = timestampRewardsEnd; TICKETS = ITickets(tickets); lockManager = ILockManager(_lockManager); } // ---------- METADATA ---------- /// @notice Get metadata URI /// @param id Token ID /// @return Metadata URI of token ID `id` function uri(uint256 id) public view override returns (string memory) { require(bytes(baseURI).length > 0, ERROR_NO_METADATA); require(id < MAX_SUPPLY, ERROR_INVALID_ID); return string(abi.encodePacked(baseURI, Strings.toString(id), uriSuffix)); } /// @notice Set metadata base URI /// @param _baseURI New metadata base URI /// @dev Doesn't emit URI event, because `id` argument isn't used function setBaseURI(string calldata _baseURI) external onlyOwner { baseURI = _baseURI; } /// @notice Set metadata URI suffix /// @param _uriSuffix New metadata URI suffix /// @dev Doesn't emit URI event, because `id` argument isn't used function setURISuffix(string calldata _uriSuffix) external onlyOwner { uriSuffix = _uriSuffix; } // ---------- TOTAL SUPPLY ---------- function totalSupplyArboria() public view returns (uint256) { return _totalSupplyBitField & _BITMASK_TOTAL_SUPPLY; } function totalSupplyIllskagaard() public view returns (uint256) { return _totalSupplyBitField >> _BITSHIFT_TOTAL_SUPPLY_ILLSKAGAARD & _BITMASK_TOTAL_SUPPLY; } function totalSupplyLacrean() public view returns (uint256) { return _totalSupplyBitField >> _BITSHIFT_TOTAL_SUPPLY_LACREAN; } function totalSupply() external view returns (uint256) { return totalSupplyArboria() + totalSupplyIllskagaard() + totalSupplyLacrean(); } // ---------- LOCK MANAGER ---------- function setLockManager(address _lockManager) external onlyOwner { emit LockManagerTransfer(address(lockManager), _lockManager); lockManager = ILockManager(_lockManager); } // ---------- REWARDS ---------- function setApprovalForRewards(address operator, bool approved) external onlyOwner { isApprovedForRewards[operator] = approved; emit ApprovalForRewards(operator, approved); } function setRewardsBitField(address owner, uint256 _rewardsBitField) external { require(isApprovedForRewards[msg.sender], ERROR_NOT_APPROVED_FOR_REWARDS); rewardsBitField[owner] = _rewardsBitField; } /// @notice Returns the token balance of the given address /// @param owner Address to check function balanceOf(address owner) public view returns (uint256) { return rewardsBitField[owner] & _BITMASK_REWARDS_TOKEN_BALANCE; } /// @notice Returns the FOA rewards balance of the given address /// @param owner Address to check function rewardsOf(address owner) external view returns (uint256 rewardsBalance) { rewardsBalance = rewardsBitField[owner] >> _BITSHIFT_REWARDS_BALANCE; uint256 lastUpdated = rewardsBitField[owner] >> _BITSHIFT_REWARDS_LAST_UPDATED & _BITMASK_REWARDS_LAST_UPDATED; if (lastUpdated != TIMESTAMP_REWARDS_END) { // Use current block timestamp or rewards end timestamp if reached uint256 timestamp = block.timestamp < TIMESTAMP_REWARDS_END ? block.timestamp : TIMESTAMP_REWARDS_END; uint256 tokenBalance = balanceOf(owner); // Calculate rewards collected since last update and add them to balance if (lastUpdated > 0) { uint256 secondsSinceLastUpdate = timestamp - lastUpdated; rewardsBalance += secondsSinceLastUpdate * REWARDS_PER_SECOND * tokenBalance; } } } function _updateRewardsForTransfer(address from, address to, uint256 tokenAmount) internal { // Use current block timestamp or rewards end timestamp if reached uint256 timestamp = block.timestamp < TIMESTAMP_REWARDS_END ? block.timestamp : TIMESTAMP_REWARDS_END; // Store bit field in memory to reduce number of SLOADs uint256 _rewardsBitField = rewardsBitField[from]; uint256 lastUpdated = _rewardsBitField >> _BITSHIFT_REWARDS_LAST_UPDATED & _BITMASK_REWARDS_LAST_UPDATED; // Update rewards bit field of `from`, unless it has already been updated since the reward emittence ended if (lastUpdated != TIMESTAMP_REWARDS_END) { uint256 tokenBalance = _rewardsBitField & _BITMASK_REWARDS_TOKEN_BALANCE; uint256 rewardsBalance = _rewardsBitField >> _BITSHIFT_REWARDS_BALANCE; // Calculate rewards collected since last update and add them to balance if (lastUpdated > 0) { uint256 secondsSinceLastUpdate = timestamp - lastUpdated; unchecked { rewardsBalance += secondsSinceLastUpdate * REWARDS_PER_SECOND * tokenBalance; } } unchecked { // Update rewards bit field of `from` with new token balance, last updated timestamp, and rewards balance rewardsBitField[from] = tokenBalance - tokenAmount | timestamp << _BITSHIFT_REWARDS_LAST_UPDATED | rewardsBalance << _BITSHIFT_REWARDS_BALANCE; } } // Store bit field in memory to reduce number of SLOADs _rewardsBitField = rewardsBitField[to]; lastUpdated = _rewardsBitField >> _BITSHIFT_REWARDS_LAST_UPDATED & _BITMASK_REWARDS_LAST_UPDATED; // Update rewards bit field of `to`, unless it has already been updated since the reward emittence ended if (lastUpdated != TIMESTAMP_REWARDS_END) { uint256 tokenBalance = _rewardsBitField & _BITMASK_REWARDS_TOKEN_BALANCE; uint256 rewardsBalance = _rewardsBitField >> _BITSHIFT_REWARDS_BALANCE; // Calculate rewards collected since last update and add them to balance if (lastUpdated > 0) { uint256 secondsSinceLastUpdate = timestamp - lastUpdated; unchecked { rewardsBalance += secondsSinceLastUpdate * REWARDS_PER_SECOND * tokenBalance; } } unchecked { // Update rewards bit field of `to` with new token balance, last updated timestamp, and rewards balance rewardsBitField[to] = tokenBalance + tokenAmount | timestamp << _BITSHIFT_REWARDS_LAST_UPDATED | rewardsBalance << _BITSHIFT_REWARDS_BALANCE; } } } function _updateRewardsForMint(address to, uint256 tokenAmount) internal { // Store bit field in memory to reduce number of SLOADs uint256 _rewardsBitField = rewardsBitField[to]; uint256 tokenBalance = _rewardsBitField & _BITMASK_REWARDS_TOKEN_BALANCE; uint256 lastUpdated = _rewardsBitField >> _BITSHIFT_REWARDS_LAST_UPDATED & _BITMASK_REWARDS_LAST_UPDATED; uint256 rewardsBalance = _rewardsBitField >> _BITSHIFT_REWARDS_BALANCE; // Calculate rewards collected since last update and add them to balance if (lastUpdated > 0) { uint256 secondsSinceLastUpdate = block.timestamp - lastUpdated; unchecked { rewardsBalance += secondsSinceLastUpdate * REWARDS_PER_SECOND * tokenBalance; } } unchecked { // Update rewards bit field of `to` with new token balance, last updated timestamp, and rewards balance rewardsBitField[to] = tokenBalance + tokenAmount | block.timestamp << _BITSHIFT_REWARDS_LAST_UPDATED | rewardsBalance << _BITSHIFT_REWARDS_BALANCE; } } // ---------- TRANSFER ---------- function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) public override { require(msg.sender == from || isApprovedForAll[from][msg.sender], ERROR_NOT_AUTHORIZED); require(id < MAX_SUPPLY, ERROR_INVALID_ID); require(amount == 1, ERROR_INVALID_AMOUNT); require(!lockManager.isLocked(address(this), msg.sender, from, to, id), ERROR_TOKEN_LOCKED); /// @solidity memory-safe-assembly assembly { // Calculate storage slot of `ownerOf[id]` let ownerOfIdSlot := add(ownerOf.slot, id) // Load address stored in `ownerOf[id]` let ownerOfId := sload(ownerOfIdSlot) // Make sure we're only using the first 160 bits of the storage slot // as the remaining 96 bits might not be zero ownerOfId := and(ownerOfId, _BITMASK_ADDRESS) // Revert with message "ERC1155B: From not token owner" if `ownerOf[id]` is not `from` if xor(ownerOfId, from) { // Load free memory position let freeMemory := mload(0x40) // Store "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) mstore(freeMemory, _ERROR_FUNCTION_SIGNATURE) // Store data offset mstore(add(freeMemory, 0x04), 0x20) // Store length of revert message mstore(add(freeMemory, 0x24), _ERROR_LENGTH_FROM_NOT_TOKEN_OWNER) // Store revert message mstore(add(freeMemory, 0x44), _ERROR_ENCODED_FROM_NOT_TOKEN_OWNER) revert(freeMemory, 0x64) } // Store address of `to` in `ownerOf[id]` sstore(ownerOfIdSlot, to) } _updateRewardsForTransfer(from, to, amount); emit TransferSingle(msg.sender, from, to, id, amount); if (to.code.length != 0) { require( ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, ERROR_UNSAFE_RECIPIENT ); } else require(to != address(0), ERROR_INVALID_RECIPIENT); } function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) public override { require(ids.length == amounts.length, ERROR_ARRAY_LENGTH_MISMATCH); require(msg.sender == from || isApprovedForAll[from][msg.sender], ERROR_NOT_AUTHORIZED); require(!lockManager.isLocked(address(this), msg.sender, from, to, ids), ERROR_TOKEN_LOCKED); /// @solidity memory-safe-assembly assembly { // Calculate length of arrays `ids` and `amounts` in bytes let arrayLength := mul(ids.length, 0x20) // Loop over all values in `ids` and `amounts` by starting // with an index offset of 0 to access the first array element // and incrementing this index by 32 after each iteration to // access the next array element until the offset reaches the end // of the arrays, at which point all values the arrays contain // have been accessed for { let indexOffset := 0x00 } lt(indexOffset, arrayLength) { indexOffset := add(indexOffset, 0x20) } { // Load current array elements by adding offset of current // array index to start of each array's data area inside calldata let id := calldataload(add(ids.offset, indexOffset)) // Revert with message "ERC1155B: Invalid ID" if `id` is higher than `MAX_ID` if gt(id, MAX_ID) { // Load free memory position // slither-disable-next-line variable-scope let freeMemory := mload(0x40) // Store "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) mstore(freeMemory, _ERROR_FUNCTION_SIGNATURE) // Store data offset mstore(add(freeMemory, 0x04), 0x20) // Store length of revert message mstore(add(freeMemory, 0x24), _ERROR_LENGTH_INVALID_ID) // Store revert message mstore(add(freeMemory, 0x44), _ERROR_ENCODED_INVALID_ID) revert(freeMemory, 0x64) } // Revert with message "ERC1155B: Invalid amount" if amount is not 1 if xor(calldataload(add(amounts.offset, indexOffset)), 1) { // Load free memory position let freeMemory := mload(0x40) // Store "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) mstore(freeMemory, _ERROR_FUNCTION_SIGNATURE) // Store data offset mstore(add(freeMemory, 0x04), 0x20) // Store length of revert message mstore(add(freeMemory, 0x24), _ERROR_LENGTH_INVALID_AMOUNT) // Store revert message mstore(add(freeMemory, 0x44), _ERROR_ENCODED_INVALID_AMOUNT) revert(freeMemory, 0x64) } // Calculate storage slot of `ownerOf[id]` let ownerOfIdSlot := add(ownerOf.slot, id) // Load address stored in `ownerOf[id]` let ownerOfId := sload(ownerOfIdSlot) // Make sure we're only using the first 160 bits of the storage slot // as the remaining 96 bits might not be zero ownerOfId := and(ownerOfId, _BITMASK_ADDRESS) // Revert with message "ERC1155B: From not token owner" if `ownerOf[id]` is not `from` if xor(ownerOfId, from) { // Load free memory position let freeMemory := mload(0x40) // Store "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) mstore(freeMemory, _ERROR_FUNCTION_SIGNATURE) // Store data offset mstore(add(freeMemory, 0x04), 0x20) // Store length of revert message mstore(add(freeMemory, 0x24), _ERROR_LENGTH_FROM_NOT_TOKEN_OWNER) // Store revert message mstore(add(freeMemory, 0x44), _ERROR_ENCODED_FROM_NOT_TOKEN_OWNER) revert(freeMemory, 0x64) } // Store address of `to` in `ownerOf[id]` sstore(ownerOfIdSlot, to) } } _updateRewardsForTransfer(from, to, ids.length); emit TransferBatch(msg.sender, from, to, ids, amounts); if (to.code.length != 0) { require( ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, ERROR_UNSAFE_RECIPIENT ); } else require(to != address(0), ERROR_INVALID_RECIPIENT); } // ---------- WHITELIST SALE ---------- /// @notice Mint a single Arboria token during whitelist sale function mintWhitelistArboria() external payable { require(msg.sender == tx.origin, ERROR_NO_CONTRACT_MINTING); require(block.timestamp >= TIMESTAMP_SALE_WHITELIST, ERROR_SALE_NOT_READY_WHITELIST); require(msg.value == MINT_PRICE, ERROR_WRONG_PRICE); // Burn whitelist ticket TICKETS.burn(msg.sender, WHITELIST_TICKET_ID, 1); _mintArboria(msg.sender); } /// @notice Mint a single Illskagaard token during whitelist sale function mintWhitelistIllskagaard() external payable { require(msg.sender == tx.origin, ERROR_NO_CONTRACT_MINTING); require(block.timestamp >= TIMESTAMP_SALE_WHITELIST, ERROR_SALE_NOT_READY_WHITELIST); require(msg.value == MINT_PRICE, ERROR_WRONG_PRICE); // Burn whitelist ticket TICKETS.burn(msg.sender, WHITELIST_TICKET_ID, 1); _mintIllskagaard(msg.sender); } /// @notice Mint a single Lacrean Empire token during whitelist sale function mintWhitelistLacrean() external payable { require(msg.sender == tx.origin, ERROR_NO_CONTRACT_MINTING); require(block.timestamp >= TIMESTAMP_SALE_WHITELIST, ERROR_SALE_NOT_READY_WHITELIST); require(msg.value == MINT_PRICE, ERROR_WRONG_PRICE); // Burn whitelist ticket TICKETS.burn(msg.sender, WHITELIST_TICKET_ID, 1); _mintLacrean(msg.sender); } /// @notice Batch mint specified amount of tokens during whitelist sale /// @param amountArboria Amount of Arboria tokens to mint /// @param amountIllskagaard Amount of Illskagaard tokens to mint /// @param amountLacrean Amount of Lacrean tokens to mint function batchMintWhitelist(uint256 amountArboria, uint256 amountIllskagaard, uint256 amountLacrean) external payable { require(msg.sender == tx.origin, ERROR_NO_CONTRACT_MINTING); require(block.timestamp >= TIMESTAMP_SALE_WHITELIST, ERROR_SALE_NOT_READY_WHITELIST); // Doing these checks and later calculating the total amount unchecked costs less gas // than not doing these checks and calculating the total amount checked require(amountArboria <= MAX_MINT_AMOUNT_PER_TX, ERROR_OVER_MAX_AMOUNT_PER_TX_ARBORIA); require(amountIllskagaard <= MAX_MINT_AMOUNT_PER_TX, ERROR_OVER_MAX_AMOUNT_PER_TX_ILLSKAGAARD); require(amountLacrean <= MAX_MINT_AMOUNT_PER_TX, ERROR_OVER_MAX_AMOUNT_PER_TX_LACREAN); uint256 amountTotal; unchecked { amountTotal = amountArboria + amountIllskagaard + amountLacrean; } require(amountTotal <= MAX_MINT_AMOUNT_PER_TX, ERROR_OVER_MAX_AMOUNT_PER_TX_TOTAL); require(amountTotal > 1, ERROR_TOTAL_AMOUNT_BELOW_TWO); unchecked { require(msg.value == amountTotal * MINT_PRICE, ERROR_WRONG_PRICE); } // Burn whitelist tickets TICKETS.burn(msg.sender, WHITELIST_TICKET_ID, amountTotal); _batchMint(msg.sender, amountArboria, amountIllskagaard, amountLacrean, amountTotal); } // ---------- PUBLIC SALE ---------- /// @notice Mint a single Arboria token during public sale function mintPublicArboria() external payable { require(msg.sender == tx.origin, ERROR_NO_CONTRACT_MINTING); require(block.timestamp >= TIMESTAMP_SALE_PUBLIC, ERROR_SALE_NOT_READY_PUBLIC); require(msg.value == MINT_PRICE, ERROR_WRONG_PRICE); _mintArboria(msg.sender); } /// @notice Mint a single Illskagaard token during public sale function mintPublicIllskagaard() external payable { require(msg.sender == tx.origin, ERROR_NO_CONTRACT_MINTING); require(block.timestamp >= TIMESTAMP_SALE_PUBLIC, ERROR_SALE_NOT_READY_PUBLIC); require(msg.value == MINT_PRICE, ERROR_WRONG_PRICE); _mintIllskagaard(msg.sender); } /// @notice Mint a single Lacrean Empire token during public sale function mintPublicLacrean() external payable { require(msg.sender == tx.origin, ERROR_NO_CONTRACT_MINTING); require(block.timestamp >= TIMESTAMP_SALE_PUBLIC, ERROR_SALE_NOT_READY_PUBLIC); require(msg.value == MINT_PRICE, ERROR_WRONG_PRICE); _mintLacrean(msg.sender); } /// @notice Batch mint specified amount of tokens during public sale /// @param amountArboria Amount of Arboria tokens to mint /// @param amountIllskagaard Amount of Illskagaard tokens to mint /// @param amountLacrean Amount of Lacrean tokens to mint function batchMintPublic(uint256 amountArboria, uint256 amountIllskagaard, uint256 amountLacrean) external payable { require(msg.sender == tx.origin, ERROR_NO_CONTRACT_MINTING); require(block.timestamp >= TIMESTAMP_SALE_PUBLIC, ERROR_SALE_NOT_READY_PUBLIC); // Doing these checks and later calculating the total amount unchecked costs less gas // than not doing these checks and calculating the total amount checked require(amountArboria <= MAX_MINT_AMOUNT_PER_TX, ERROR_OVER_MAX_AMOUNT_PER_TX_ARBORIA); require(amountIllskagaard <= MAX_MINT_AMOUNT_PER_TX, ERROR_OVER_MAX_AMOUNT_PER_TX_ILLSKAGAARD); require(amountLacrean <= MAX_MINT_AMOUNT_PER_TX, ERROR_OVER_MAX_AMOUNT_PER_TX_LACREAN); uint256 amountTotal; unchecked { amountTotal = amountArboria + amountIllskagaard + amountLacrean; } require(amountTotal <= MAX_MINT_AMOUNT_PER_TX, ERROR_OVER_MAX_AMOUNT_PER_TX_TOTAL); require(amountTotal > 1, ERROR_TOTAL_AMOUNT_BELOW_TWO); unchecked { require(msg.value == amountTotal * MINT_PRICE, ERROR_WRONG_PRICE); } _batchMint(msg.sender, amountArboria, amountIllskagaard, amountLacrean, amountTotal); } // ---------- MINT ---------- /// @notice Mint a single Lacrean Empire token as contract owner /// @param to Receiver of minted token function mintOwnerLacrean(address to) external onlyOwner { _mintLacrean(to); } /// @notice Batch mint as contract owner /// @param tos Receivers of minted tokens /// @param amountsArboria Amounts of Arboria tokens to mint /// @param amountsIllskagaard Amounts of Illskagaard tokens to mint /// @param amountsLacrean Amounts of Lacrean tokens to mint function batchMintOwner( address[] calldata tos, uint256[] calldata amountsArboria, uint256[] calldata amountsIllskagaard, uint256[] calldata amountsLacrean ) external onlyOwner { require( tos.length == amountsArboria.length && amountsArboria.length == amountsIllskagaard.length && amountsIllskagaard.length == amountsLacrean.length, ERROR_ARRAY_LENGTH_MISMATCH ); // Calculate array length in bytes uint256 arrayLength; unchecked { arrayLength = tos.length * 0x20; } for (uint256 indexOffset = 0x00; indexOffset < arrayLength;) { address to; uint256 amountArboria; uint256 amountIllskagaard; uint256 amountLacrean; /// @solidity memory-safe-assembly assembly { // Load current array elements by adding offset of current // array index to start of each array's data area inside calldata to := calldataload(add(tos.offset, indexOffset)) amountArboria := calldataload(add(amountsArboria.offset, indexOffset)) amountIllskagaard := calldataload(add(amountsIllskagaard.offset, indexOffset)) amountLacrean := calldataload(add(amountsLacrean.offset, indexOffset)) // Increment index offset by 32 for next iteration indexOffset := add(indexOffset, 0x20) } unchecked { uint256 amountTotal = amountArboria + amountIllskagaard + amountLacrean; _batchMint(to, amountArboria, amountIllskagaard, amountLacrean, amountTotal); } } } /// @dev Mint a single Arboria token /// @param to Receiver of minted token function _mintArboria(address to) internal { // Total supply of Arboria tokens is stored in the first 16 bits of the bit field uint256 id = _totalSupplyBitField & _BITMASK_TOTAL_SUPPLY; require(id < MAX_SUPPLY_PER_FACTION, ERROR_REACHED_MAX_SUPPLY_ARBORIA); /// @solidity memory-safe-assembly assembly { // Calculate storage slot of `ownerOf[id]` let ownerOfIdSlot := add(ownerOf.slot, id) // Store address of `to` in `ownerOf[id]` sstore(ownerOfIdSlot, to) } unchecked { // Incrementing the whole bit field increments just the total supply of // Arboria tokens, because only the value stored in the first bits gets updated _totalSupplyBitField++; } _updateRewardsForMint(to, 1); emit TransferSingle(msg.sender, address(0), to, id, 1); } /// @dev Mint a single Illskagaard token /// @param to Receiver of minted token function _mintIllskagaard(address to) internal { // Store bit field in memory to reduce number of SLOADs uint256 totalSupplyBitField = _totalSupplyBitField; // Total supply of Illskagaard tokens is stored in the second 16 bits of the bit field uint256 _totalSupplyIllskagaard = totalSupplyBitField >> _BITSHIFT_TOTAL_SUPPLY_ILLSKAGAARD & _BITMASK_TOTAL_SUPPLY; require(_totalSupplyIllskagaard < MAX_SUPPLY_PER_FACTION, ERROR_REACHED_MAX_SUPPLY_ILLSKAGAARD); uint256 id; unchecked { // Illskagaard token IDs start at 6000 id = ID_OFFSET_ILLSKAGAARD + _totalSupplyIllskagaard; } /// @solidity memory-safe-assembly assembly { // Calculate storage slot of `ownerOf[id]` let ownerOfIdSlot := add(ownerOf.slot, id) // Store address of `to` in `ownerOf[id]` sstore(ownerOfIdSlot, to) } unchecked { // Second 16 bits need to be all set to 0 before the new total supply of // Illskagaard tokens can be stored _totalSupplyBitField = totalSupplyBitField & _BITMASK_TOTAL_SUPPLY_ILLSKAGAARD | ++_totalSupplyIllskagaard << _BITSHIFT_TOTAL_SUPPLY_ILLSKAGAARD; } _updateRewardsForMint(to, 1); emit TransferSingle(msg.sender, address(0), to, id, 1); } /// @dev Mint a single Lacrean Empire token /// @param to Receiver of minted token function _mintLacrean(address to) internal { // Store bit field in memory to reduce number of SLOADs uint256 totalSupplyBitField = _totalSupplyBitField; // Total supply of Lacrean Empire tokens is stored in the third 16 bits of the bit field uint256 _totalSupplyLacrean = totalSupplyBitField >> _BITSHIFT_TOTAL_SUPPLY_LACREAN; require(_totalSupplyLacrean < MAX_SUPPLY_PER_FACTION, ERROR_REACHED_MAX_SUPPLY_LACREAN); uint256 id; unchecked { // Lacrean Empire token IDs start at 12000 id = ID_OFFSET_LACREAN + _totalSupplyLacrean; } /// @solidity memory-safe-assembly assembly { // Calculate storage slot of `ownerOf[id]` let ownerOfIdSlot := add(ownerOf.slot, id) // Store address of `to` in `ownerOf[id]` sstore(ownerOfIdSlot, to) } unchecked { // Third 16 bits need to be all set to 0 before the new total supply of // Lacrean Empire tokens can be stored _totalSupplyBitField = totalSupplyBitField & _BITMASK_TOTAL_SUPPLY_LACREAN | ++_totalSupplyLacrean << _BITSHIFT_TOTAL_SUPPLY_LACREAN; } _updateRewardsForMint(to, 1); emit TransferSingle(msg.sender, address(0), to, id, 1); } /// @notice Batch mint specified amount of tokens /// @param to Receiver of minted tokens /// @param amountArboria Amount of Arboria tokens to mint /// @param amountIllskagaard Amount of Illskagaard tokens to mint /// @param amountLacrean Amount of Lacrean tokens to mint /// @param amountTotal Total amount of tokens to mint function _batchMint( address to, uint256 amountArboria, uint256 amountIllskagaard, uint256 amountLacrean, uint256 amountTotal ) internal { // Token IDs and amounts are collected in arrays to later emit the TransferBatch event uint256[] memory ids = new uint256[](amountTotal); // Token amounts are all 1 uint256[] memory amounts = new uint256[](amountTotal); // Keep track of the current index offsets for each array uint256 offsetIds; uint256 offsetAmounts; /// @solidity memory-safe-assembly assembly { // Skip the first 32 bytes containing the array length offsetIds := add(ids, 0x20) offsetAmounts := add(amounts, 0x20) } // Store bit field in memory to reduce number of SLOADs uint256 totalSupplyBitField = _totalSupplyBitField; // New bit field gets updated in memory to reduce number of SSTOREs // _totalSupplyBitField is only updated once after all tokens are minted uint256 newTotalSupplyBitField = totalSupplyBitField; if (amountArboria > 0) { // Total supply of Arboria tokens is stored in the first 16 bits of the bit field uint256 _totalSupplyArboria = totalSupplyBitField & _BITMASK_TOTAL_SUPPLY; uint256 newTotalSupplyArboria; unchecked { newTotalSupplyArboria = _totalSupplyArboria + amountArboria; } require(newTotalSupplyArboria <= MAX_SUPPLY_PER_FACTION, ERROR_REACHED_MAX_SUPPLY_ARBORIA); /// @solidity memory-safe-assembly assembly { // Set owner of Arboria token IDs for { let id := _totalSupplyArboria } lt(id, newTotalSupplyArboria) { id := add(id, 1) } { // Calculate storage slot of `ownerOf[id]` let ownerOfIdSlot := add(ownerOf.slot, id) // Store address of `to` in `ownerOf[id]` sstore(ownerOfIdSlot, to) // Store id and amount in the corresponding memory arrays mstore(offsetIds, id) mstore(offsetAmounts, 1) // Increment index offsets by 32 for next iteration offsetIds := add(offsetIds, 0x20) offsetAmounts := add(offsetAmounts, 0x20) } } // First 16 bits need to be all set to 0 before the new total supply of Arboria tokens can be stored newTotalSupplyBitField = newTotalSupplyBitField & _BITMASK_TOTAL_SUPPLY_ARBORIA | newTotalSupplyArboria; } if (amountIllskagaard > 0) { // Total supply of Illskagaard tokens is stored in the second 16 bits of the bit field uint256 _totalSupplyIllskagaard = totalSupplyBitField >> _BITSHIFT_TOTAL_SUPPLY_ILLSKAGAARD & _BITMASK_TOTAL_SUPPLY; uint256 newTotalSupplyIllskagaard; unchecked { newTotalSupplyIllskagaard = _totalSupplyIllskagaard + amountIllskagaard; } require(newTotalSupplyIllskagaard <= MAX_SUPPLY_PER_FACTION, ERROR_REACHED_MAX_SUPPLY_ILLSKAGAARD); /// @solidity memory-safe-assembly assembly { // Set owner of Illskagaard token IDs for { let i := _totalSupplyIllskagaard } lt(i, newTotalSupplyIllskagaard) { i := add(i, 1) } { // Illskagaard token IDs start at 6000 let id := add(ID_OFFSET_ILLSKAGAARD, i) // Calculate storage slot of `ownerOf[id]` let ownerOfIdSlot := add(ownerOf.slot, id) // Store address of `to` in `ownerOf[id]` sstore(ownerOfIdSlot, to) // Store id and amount in the corresponding memory arrays mstore(offsetIds, id) mstore(offsetAmounts, 1) // Increment index offsets by 32 for next iteration offsetIds := add(offsetIds, 0x20) offsetAmounts := add(offsetAmounts, 0x20) } } // Second 16 bits need to be all set to 0 before the new total supply of Illskagaard tokens can be stored newTotalSupplyBitField = newTotalSupplyBitField & _BITMASK_TOTAL_SUPPLY_ILLSKAGAARD | newTotalSupplyIllskagaard << _BITSHIFT_TOTAL_SUPPLY_ILLSKAGAARD; } if (amountLacrean > 0) { // Total supply of Lacrean Empire tokens is stored in the third 16 bits of the bit field uint256 _totalSupplyLacrean = totalSupplyBitField >> _BITSHIFT_TOTAL_SUPPLY_LACREAN; uint256 newTotalSupplyLacrean; unchecked { newTotalSupplyLacrean = _totalSupplyLacrean + amountLacrean; } require(newTotalSupplyLacrean <= MAX_SUPPLY_PER_FACTION, ERROR_REACHED_MAX_SUPPLY_LACREAN); /// @solidity memory-safe-assembly assembly { // Set owner of Lacrean Empire token IDs for { let i := _totalSupplyLacrean } lt(i, newTotalSupplyLacrean) { i := add(i, 1) } { // Lacrean Empire token IDs start at 12000 let id := add(ID_OFFSET_LACREAN, i) // Calculate storage slot of `ownerOf[id]` let ownerOfIdSlot := add(ownerOf.slot, id) // Store address of `to` in `ownerOf[id]` sstore(ownerOfIdSlot, to) // Store id and amount in the corresponding memory arrays mstore(offsetIds, id) mstore(offsetAmounts, 1) // Increment index offsets by 32 for next iteration offsetIds := add(offsetIds, 0x20) offsetAmounts := add(offsetAmounts, 0x20) } } // Third 16 bits need to be all set to 0 before the new total supply of Lacrean Empire tokens can be stored newTotalSupplyBitField = newTotalSupplyBitField & _BITMASK_TOTAL_SUPPLY_LACREAN | newTotalSupplyLacrean << _BITSHIFT_TOTAL_SUPPLY_LACREAN; } // slither-disable-next-line costly-loop _totalSupplyBitField = newTotalSupplyBitField; _updateRewardsForMint(to, amountTotal); emit TransferBatch(msg.sender, address(0), to, ids, amounts); } // ---------- OWNERS ---------- function owners() external view returns (address[MAX_SUPPLY] memory) { return ownerOf; } // ---------- WITHDRAW ---------- /// @notice Withdraw all Ether stored in this contract to address of contract owner function withdraw() external onlyOwner { payable(msg.sender).transfer(address(this).balance); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @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 Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { 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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @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); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.14; import {ERC1155TokenReceiver} from "solmate/tokens/ERC1155.sol"; /// @title Minimalist and gas efficient ERC1155 implementation optimized for single supply ids /// @author Solarbots (https://solarbots.io) /// @notice Based on Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155B.sol) abstract contract ERC1155B { // ---------- CONSTANTS ---------- /// @notice Maximum amount of tokens that can be minted uint256 public constant MAX_SUPPLY = 18_000; /// @notice Maximum token ID /// @dev Inline assembly does not support non-number constants like `MAX_SUPPLY - 1` uint256 public constant MAX_ID = 17_999; string public constant ERROR_ARRAY_LENGTH_MISMATCH = "ERC1155B: Array length mismatch"; string public constant ERROR_FROM_NOT_TOKEN_OWNER = "ERC1155B: From not token owner"; string public constant ERROR_ID_ALREADY_MINTED = "ERC1155B: ID already minted"; string public constant ERROR_ID_NOT_MINTED = "ERC1155B: ID not minted"; string public constant ERROR_INVALID_AMOUNT = "ERC1155B: Invalid amount"; string public constant ERROR_INVALID_FROM = "ERC1155B: Invalid from"; string public constant ERROR_INVALID_ID = "ERC1155B: Invalid ID"; string public constant ERROR_INVALID_RECIPIENT = "ERC1155B: Invalid recipient"; string public constant ERROR_NOT_AUTHORIZED = "ERC1155B: Not authorized"; string public constant ERROR_UNSAFE_RECIPIENT = "ERC1155B: Unsafe recipient"; /// @dev bytes32(abi.encodePacked("ERC1155B: Invalid ID")) bytes32 internal constant _ERROR_ENCODED_INVALID_ID = 0x45524331313535423a20496e76616c6964204944000000000000000000000000; /// @dev bytes32(abi.encodePacked("ERC1155B: Invalid amount")) bytes32 internal constant _ERROR_ENCODED_INVALID_AMOUNT = 0x45524331313535423a20496e76616c696420616d6f756e740000000000000000; /// @dev bytes32(abi.encodePacked("ERC1155B: From not token owner")) bytes32 internal constant _ERROR_ENCODED_FROM_NOT_TOKEN_OWNER = 0x45524331313535423a2046726f6d206e6f7420746f6b656e206f776e65720000; /// @dev "ERC1155B: Invalid ID" is 20 characters long uint256 internal constant _ERROR_LENGTH_INVALID_ID = 20; /// @dev "ERC1155B: Invalid amount" is 24 characters long uint256 internal constant _ERROR_LENGTH_INVALID_AMOUNT = 24; /// @dev "ERC1155B: From not token owner" is 30 characters long uint256 internal constant _ERROR_LENGTH_FROM_NOT_TOKEN_OWNER = 30; /// @dev "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) bytes32 internal constant _ERROR_FUNCTION_SIGNATURE = 0x08c379a000000000000000000000000000000000000000000000000000000000; /// @dev Inline assembly does not support non-number constants like `type(uint160).max` uint256 internal constant _BITMASK_ADDRESS = 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff; // ---------- STATE ---------- address[MAX_SUPPLY] public ownerOf; mapping(address => mapping(address => bool)) public isApprovedForAll; // ---------- EVENTS ---------- event URI(string value, uint256 indexed id); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); event TransferSingle( address indexed operator, address indexed from, address indexed to, uint256 id, uint256 amount ); event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] amounts ); // ---------- ERC-165 ---------- // slither-disable-next-line external-function function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155 interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI } // ---------- METADATA ---------- // slither-disable-next-line external-function function uri(uint256 id) public view virtual returns (string memory); // ---------- APPROVAL ---------- // slither-disable-next-line external-function function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } // ---------- BALANCE ---------- function balanceOf(address owner, uint256 id) public view virtual returns (uint256 bal) { address idOwner = ownerOf[id]; assembly { // We avoid branching by using assembly to take // the bool output of eq() and use it as a uint. bal := eq(idOwner, owner) } } // slither-disable-next-line external-function function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) public view virtual returns (uint256[] memory balances) { require(owners.length == ids.length, ERROR_ARRAY_LENGTH_MISMATCH); balances = new uint256[](owners.length); // Unchecked because the only math done is incrementing // the array index counter which cannot possibly overflow. unchecked { for (uint256 i = 0; i < owners.length; ++i) { balances[i] = balanceOf(owners[i], ids[i]); } } } // ---------- TRANSFER ---------- // slither-disable-next-line external-function function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) public virtual { require(msg.sender == from || isApprovedForAll[from][msg.sender], ERROR_NOT_AUTHORIZED); require(id < MAX_SUPPLY, ERROR_INVALID_ID); require(amount == 1, ERROR_INVALID_AMOUNT); /// @solidity memory-safe-assembly assembly { // Calculate storage slot of `ownerOf[id]` let ownerOfIdSlot := add(ownerOf.slot, id) // Load address stored in `ownerOf[id]` let ownerOfId := sload(ownerOfIdSlot) // Make sure we're only using the first 160 bits of the storage slot // as the remaining 96 bits might not be zero ownerOfId := and(ownerOfId, _BITMASK_ADDRESS) // Revert with message "ERC1155B: From not token owner" if `ownerOf[id]` is not `from` if xor(ownerOfId, from) { // Load free memory position let freeMemory := mload(0x40) // Store "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) mstore(freeMemory, _ERROR_FUNCTION_SIGNATURE) // Store data offset mstore(add(freeMemory, 0x04), 0x20) // Store length of revert message mstore(add(freeMemory, 0x24), _ERROR_LENGTH_FROM_NOT_TOKEN_OWNER) // Store revert message mstore(add(freeMemory, 0x44), _ERROR_ENCODED_FROM_NOT_TOKEN_OWNER) revert(freeMemory, 0x64) } // Store address of `to` in `ownerOf[id]` sstore(ownerOfIdSlot, to) } emit TransferSingle(msg.sender, from, to, id, amount); if (to.code.length != 0) { require( ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, ERROR_UNSAFE_RECIPIENT ); } else require(to != address(0), ERROR_INVALID_RECIPIENT); } // slither-disable-next-line external-function function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) public virtual { require(ids.length == amounts.length, ERROR_ARRAY_LENGTH_MISMATCH); require(msg.sender == from || isApprovedForAll[from][msg.sender], ERROR_NOT_AUTHORIZED); /// @solidity memory-safe-assembly assembly { // Calculate length of arrays `ids` and `amounts` in bytes let arrayLength := mul(ids.length, 0x20) // Loop over all values in `ids` and `amounts` by starting // with an index offset of 0 to access the first array element // and incrementing this index by 32 after each iteration to // access the next array element until the offset reaches the end // of the arrays, at which point all values the arrays contain // have been accessed for { let indexOffset := 0x00 } lt(indexOffset, arrayLength) { indexOffset := add(indexOffset, 0x20) } { // Load current array elements by adding offset of current // array index to start of each array's data area inside calldata let id := calldataload(add(ids.offset, indexOffset)) // Revert with message "ERC1155B: Invalid ID" if `id` is higher than `MAX_ID` if gt(id, MAX_ID) { // Load free memory position // slither-disable-next-line variable-scope let freeMemory := mload(0x40) // Store "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) mstore(freeMemory, _ERROR_FUNCTION_SIGNATURE) // Store data offset mstore(add(freeMemory, 0x04), 0x20) // Store length of revert message mstore(add(freeMemory, 0x24), _ERROR_LENGTH_INVALID_ID) // Store revert message mstore(add(freeMemory, 0x44), _ERROR_ENCODED_INVALID_ID) revert(freeMemory, 0x64) } // Revert with message "ERC1155B: Invalid amount" if amount is not 1 if xor(calldataload(add(amounts.offset, indexOffset)), 1) { // Load free memory position let freeMemory := mload(0x40) // Store "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) mstore(freeMemory, _ERROR_FUNCTION_SIGNATURE) // Store data offset mstore(add(freeMemory, 0x04), 0x20) // Store length of revert message mstore(add(freeMemory, 0x24), _ERROR_LENGTH_INVALID_AMOUNT) // Store revert message mstore(add(freeMemory, 0x44), _ERROR_ENCODED_INVALID_AMOUNT) revert(freeMemory, 0x64) } // Calculate storage slot of `ownerOf[id]` let ownerOfIdSlot := add(ownerOf.slot, id) // Load address stored in `ownerOf[id]` let ownerOfId := sload(ownerOfIdSlot) // Make sure we're only using the first 160 bits of the storage slot // as the remaining 96 bits might not be zero ownerOfId := and(ownerOfId, _BITMASK_ADDRESS) // Revert with message "ERC1155B: From not token owner" if `ownerOf[id]` is not `from` if xor(ownerOfId, from) { // Load free memory position let freeMemory := mload(0x40) // Store "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) mstore(freeMemory, _ERROR_FUNCTION_SIGNATURE) // Store data offset mstore(add(freeMemory, 0x04), 0x20) // Store length of revert message mstore(add(freeMemory, 0x24), _ERROR_LENGTH_FROM_NOT_TOKEN_OWNER) // Store revert message mstore(add(freeMemory, 0x44), _ERROR_ENCODED_FROM_NOT_TOKEN_OWNER) revert(freeMemory, 0x64) } // Store address of `to` in `ownerOf[id]` sstore(ownerOfIdSlot, to) } } emit TransferBatch(msg.sender, from, to, ids, amounts); if (to.code.length != 0) { require( ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, ERROR_UNSAFE_RECIPIENT ); } else require(to != address(0), ERROR_INVALID_RECIPIENT); } // ---------- MINT ---------- // slither-disable-next-line dead-code function _mint( address to, uint256 id, bytes memory data ) internal virtual { // Minting twice would effectively be a force transfer. require(ownerOf[id] == address(0), ERROR_ID_ALREADY_MINTED); ownerOf[id] = to; emit TransferSingle(msg.sender, address(0), to, id, 1); if (to.code.length != 0) { require( ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, 1, data) == ERC1155TokenReceiver.onERC1155Received.selector, ERROR_UNSAFE_RECIPIENT ); } else require(to != address(0), ERROR_INVALID_RECIPIENT); } // slither-disable-next-line dead-code function _batchMint( address to, uint256[] memory ids, bytes memory data ) internal virtual { uint256 idsLength = ids.length; // Saves MLOADs. // Generate an amounts array locally to use in the event below. uint256[] memory amounts = new uint256[](idsLength); uint256 id; // Storing outside the loop saves ~7 gas per iteration. // Unchecked because the only math done is incrementing // the array index counter which cannot possibly overflow. unchecked { for (uint256 i = 0; i < idsLength; ++i) { id = ids[i]; // Minting twice would effectively be a force transfer. require(ownerOf[id] == address(0), ERROR_ID_ALREADY_MINTED); ownerOf[id] = to; amounts[i] = 1; } } emit TransferBatch(msg.sender, address(0), to, ids, amounts); if (to.code.length != 0) { require( ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, ERROR_UNSAFE_RECIPIENT ); } else require(to != address(0), ERROR_INVALID_RECIPIENT); } // ---------- BURN ---------- // slither-disable-next-line dead-code function _burn(uint256 id) internal virtual { address owner = ownerOf[id]; require(owner != address(0), ERROR_ID_NOT_MINTED); ownerOf[id] = address(0); emit TransferSingle(msg.sender, owner, address(0), id, 1); } // slither-disable-next-line dead-code function _batchBurn(address from, uint256[] memory ids) internal virtual { // Burning unminted tokens makes no sense. require(from != address(0), ERROR_INVALID_FROM); uint256 idsLength = ids.length; // Saves MLOADs. // Generate an amounts array locally to use in the event below. uint256[] memory amounts = new uint256[](idsLength); uint256 id; // Storing outside the loop saves ~7 gas per iteration. // Unchecked because the only math done is incrementing // the array index counter which cannot possibly overflow. unchecked { for (uint256 i = 0; i < idsLength; ++i) { id = ids[i]; require(from == ownerOf[id], ERROR_FROM_NOT_TOKEN_OWNER); ownerOf[id] = address(0); amounts[i] = 1; } } emit TransferBatch(msg.sender, from, address(0), ids, amounts); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.14; /// @title Solarbots Lock Manager Interface /// @author Solarbots (https://solarbots.io) interface ILockManager { function isLocked(address collection, address operator, address from, address to, uint256 id) external returns (bool); function isLocked(address collection, address operator, address from, address to, uint256[] calldata ids) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.14; /// @title Solarbots Tickets Interface /// @author Solarbots (https://solarbots.io) interface ITickets { function burn(address from, uint256 id, uint256 amount) external; }
// SPDX-License-Identifier: MIT // 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; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; /// @notice Minimalist and gas efficient standard ERC1155 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event TransferSingle( address indexed operator, address indexed from, address indexed to, uint256 id, uint256 amount ); event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] amounts ); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); event URI(string value, uint256 indexed id); /*////////////////////////////////////////////////////////////// ERC1155 STORAGE //////////////////////////////////////////////////////////////*/ mapping(address => mapping(uint256 => uint256)) public balanceOf; mapping(address => mapping(address => bool)) public isApprovedForAll; /*////////////////////////////////////////////////////////////// METADATA LOGIC //////////////////////////////////////////////////////////////*/ function uri(uint256 id) public view virtual returns (string memory); /*////////////////////////////////////////////////////////////// ERC1155 LOGIC //////////////////////////////////////////////////////////////*/ function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) public virtual { require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); balanceOf[from][id] -= amount; balanceOf[to][id] += amount; emit TransferSingle(msg.sender, from, to, id, amount); if (to.code.length != 0) { require( ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } else require(to != address(0), "INVALID_RECIPIENT"); } function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) public virtual { require(ids.length == amounts.length, "LENGTH_MISMATCH"); require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); // Storing these outside the loop saves ~15 gas per iteration. uint256 id; uint256 amount; for (uint256 i = 0; i < ids.length; ) { id = ids[i]; amount = amounts[i]; balanceOf[from][id] -= amount; balanceOf[to][id] += amount; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, from, to, ids, amounts); if (to.code.length != 0) { require( ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, "UNSAFE_RECIPIENT" ); } else require(to != address(0), "INVALID_RECIPIENT"); } function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) public view virtual returns (uint256[] memory balances) { require(owners.length == ids.length, "LENGTH_MISMATCH"); balances = new uint256[](owners.length); // Unchecked because the only math done is incrementing // the array index counter which cannot possibly overflow. unchecked { for (uint256 i = 0; i < owners.length; ++i) { balances[i] = balanceOf[owners[i]][ids[i]]; } } } /*////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155 interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint( address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { balanceOf[to][id] += amount; emit TransferSingle(msg.sender, address(0), to, id, amount); if (to.code.length != 0) { require( ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } else require(to != address(0), "INVALID_RECIPIENT"); } function _batchMint( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); for (uint256 i = 0; i < idsLength; ) { balanceOf[to][ids[i]] += amounts[i]; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, address(0), to, ids, amounts); if (to.code.length != 0) { require( ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, "UNSAFE_RECIPIENT" ); } else require(to != address(0), "INVALID_RECIPIENT"); } function _batchBurn( address from, uint256[] memory ids, uint256[] memory amounts ) internal virtual { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); for (uint256 i = 0; i < idsLength; ) { balanceOf[from][ids[i]] -= amounts[i]; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, from, address(0), ids, amounts); } function _burn( address from, uint256 id, uint256 amount ) internal virtual { balanceOf[from][id] -= amount; emit TransferSingle(msg.sender, from, address(0), id, amount); } } /// @notice A generic interface for a contract which properly accepts ERC1155 tokens. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155TokenReceiver { function onERC1155Received( address, address, uint256, uint256, bytes calldata ) external virtual returns (bytes4) { return ERC1155TokenReceiver.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] calldata, uint256[] calldata, bytes calldata ) external virtual returns (bytes4) { return ERC1155TokenReceiver.onERC1155BatchReceived.selector; } }
{ "remappings": [ "ds-test/=lib/solmate/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "openzeppelin/=lib/openzeppelin-contracts/contracts/", "script/=script/", "solmate/=lib/solmate/src/", "src/=src/", "test/=test/", "src/=src/", "test/=test/", "script/=script/" ], "optimizer": { "enabled": true, "runs": 10000 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"timestampSaleWhitelist","type":"uint256"},{"internalType":"uint256","name":"timestampSalePublic","type":"uint256"},{"internalType":"uint256","name":"timestampRewardsEnd","type":"uint256"},{"internalType":"address","name":"tickets","type":"address"},{"internalType":"address","name":"_lockManager","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousLockManager","type":"address"},{"indexed":true,"internalType":"address","name":"newLockManager","type":"address"}],"name":"LockManagerTransfer","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[],"name":"ERROR_ARRAY_LENGTH_MISMATCH","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_FROM_NOT_TOKEN_OWNER","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_ID_ALREADY_MINTED","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_ID_NOT_MINTED","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_INVALID_AMOUNT","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_INVALID_FROM","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_INVALID_ID","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_INVALID_RECIPIENT","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_NOT_APPROVED_FOR_REWARDS","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_NOT_AUTHORIZED","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_NO_CONTRACT_MINTING","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_NO_METADATA","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_OVER_MAX_AMOUNT_PER_TX_ARBORIA","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_OVER_MAX_AMOUNT_PER_TX_ILLSKAGAARD","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_OVER_MAX_AMOUNT_PER_TX_LACREAN","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_OVER_MAX_AMOUNT_PER_TX_TOTAL","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_REACHED_MAX_SUPPLY_ARBORIA","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_REACHED_MAX_SUPPLY_ILLSKAGAARD","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_REACHED_MAX_SUPPLY_LACREAN","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_SALE_NOT_READY_PUBLIC","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_SALE_NOT_READY_WHITELIST","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_TOKEN_LOCKED","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_TOTAL_AMOUNT_BELOW_TWO","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_UNSAFE_RECIPIENT","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERROR_WRONG_PRICE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ID_OFFSET_ILLSKAGAARD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ID_OFFSET_LACREAN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_MINT_AMOUNT_PER_TX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY_PER_FACTION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARDS_PER_SECOND","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TICKETS","outputs":[{"internalType":"contract ITickets","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TIMESTAMP_REWARDS_END","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TIMESTAMP_SALE_PUBLIC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TIMESTAMP_SALE_WHITELIST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WHITELIST_TICKET_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"bal","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"owners","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"tos","type":"address[]"},{"internalType":"uint256[]","name":"amountsArboria","type":"uint256[]"},{"internalType":"uint256[]","name":"amountsIllskagaard","type":"uint256[]"},{"internalType":"uint256[]","name":"amountsLacrean","type":"uint256[]"}],"name":"batchMintOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountArboria","type":"uint256"},{"internalType":"uint256","name":"amountIllskagaard","type":"uint256"},{"internalType":"uint256","name":"amountLacrean","type":"uint256"}],"name":"batchMintPublic","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountArboria","type":"uint256"},{"internalType":"uint256","name":"amountIllskagaard","type":"uint256"},{"internalType":"uint256","name":"amountLacrean","type":"uint256"}],"name":"batchMintWhitelist","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForRewards","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockManager","outputs":[{"internalType":"contract ILockManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mintOwnerLacrean","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintPublicArboria","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintPublicIllskagaard","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintPublicLacrean","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintWhitelistArboria","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintWhitelistIllskagaard","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintWhitelistLacrean","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owners","outputs":[{"internalType":"address[18000]","name":"","type":"address[18000]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardsBitField","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"rewardsOf","outputs":[{"internalType":"uint256","name":"rewardsBalance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lockManager","type":"address"}],"name":"setLockManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"_rewardsBitField","type":"uint256"}],"name":"setRewardsBitField","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriSuffix","type":"string"}],"name":"setURISuffix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupplyArboria","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupplyIllskagaard","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupplyLacrean","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uriSuffix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101006040523480156200001257600080fd5b5060405162004a1a38038062004a1a8339810160408190526200003591620000f5565b620000403362000085565b6200004b8662000085565b60a09490945260c0929092526080526001600160a01b0390811660e05261465480546001600160a01b03191691909216179055506200015b565b61465180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b0381168114620000f057600080fd5b919050565b60008060008060008060c087890312156200010f57600080fd5b6200011a87620000d8565b95506020870151945060408701519350606087015192506200013f60808801620000d8565b91506200014f60a08801620000d8565b90509295509295509295565b60805160a05160c05160e0516148006200021a6000396000818161070a01528181611b81015281816121a50152818161247e015261294b01526000818161076b015281816111ae01528181611d5b015281816125b20152612a12015260008181610a0b01528181611a8e01528181611f770152818161238b0152612858015260008181610b2201528181611c1b01528181611c4401528181611c6b0152818161356b01528181613592015281816135e2015261368a01526148006000f3fe60806040526004361061053c5760003560e01c806370a08231116102af578063affe39c111610179578063dd74d3b7116100d6578063efd52b8b1161008a578063f242432a1161006f578063f242432a14610fb0578063f2fde38b14610fd0578063f806b10114610ff057600080fd5b8063efd52b8b14610f86578063f1d91b1214610f9b57600080fd5b8063e4a1ada4116100bb578063e4a1ada414610f20578063e985e9c514610f35578063ea39260014610f7157600080fd5b8063dd74d3b714610ecf578063deedfdbd14610f0057600080fd5b8063c1049e801161012d578063c8d3403911610112578063c8d3403914610e1f578063d39fbaa414610e68578063dbcfd08f14610eb157600080fd5b8063c1049e8014610db6578063c64a0b8b14610dff57600080fd5b8063bdb6fe2a1161015e578063bdb6fe2a14610d7d578063bfd7253f14610d92578063c002d23d14610d9a57600080fd5b8063affe39c114610d53578063b9be77b214610d7557600080fd5b80638da5cb5b11610227578063a113152b116101db578063a42bfe6d116101c0578063a42bfe6d14610cf2578063a4a4003814610d12578063acca30a214610d3257600080fd5b8063a113152b14610c89578063a22cb46514610cd257600080fd5b80639030d1bb1161020c5780639030d1bb14610c4c57806398c7798414610c6c578063a0afde1514610c8157600080fd5b80638da5cb5b14610c255780638f13c2a414610c4457600080fd5b8063802e79181161027e57806386aaf9341161026357806386aaf93414610b7e578063873b4aa914610bc7578063878de91e14610c1057600080fd5b8063802e791814610b4457806381b3e57514610b5e57600080fd5b806370a0823114610a77578063715018a614610ab25780637999567114610ac75780637aeb357314610b1057600080fd5b80632eb2c2d61161040b5780634ee6262d11610368578063576793491161031c5780636352211e116103015780636352211e14610a2d5780636a01be5314610a4d5780636c0360eb14610a6257600080fd5b806357679349146109b057806358e96d5f146109f957600080fd5b806351f977041161034d57806351f97704146109685780635503a0e81461097b57806355f804b31461099057600080fd5b80634ee6262d1461091f5780634f9bba2c1461083957600080fd5b8063479ba7ae116103bf5780634d58026c116103a45780634d58026c146108a15780634d7e41d5146108a95780634e1273f4146108f257600080fd5b8063479ba7ae1461086c5780634c09e3e61461088c57600080fd5b806335f743ae116103f057806335f743ae146108395780633ccfd60b1461084f5780633e4af9c51461086457600080fd5b80632eb2c2d61461080357806332cb6b0c1461082357600080fd5b80630e89341c116104b95780631adc62d81161046d578063207e3cc311610452578063207e3cc3146107a75780632552a1d0146107d55780632d960a4c146107ea57600080fd5b80631adc62d8146107595780631d84cee91461078d57600080fd5b806318160ddd1161049e57806318160ddd146106e357806318c33e46146106f8578063192d4df61461074457600080fd5b80630e89341c146106ad57806317bac052146106cd57600080fd5b80630ae349f4116105105780630d6f23cd116104f55780630d6f23cd146106065780630df1f7c71461064f5780630e0847211461069857600080fd5b80630ae349f4146105db5780630b32f0b2146105f157600080fd5b8062fdd58e1461054157806301ffc9a71461057457806303e56262146105a457806309ef6527146105c6575b600080fd5b34801561054d57600080fd5b5061056161055c366004613b70565b611039565b6040519081526020015b60405180910390f35b34801561058057600080fd5b5061059461058f366004613bc8565b611066565b604051901515815260200161056b565b3480156105b057600080fd5b506105b961114b565b60405161056b9190613c18565b3480156105d257600080fd5b50610561600581565b3480156105e757600080fd5b50610561612ee081565b6106046105ff366004613c69565b611167565b005b34801561061257600080fd5b506105b96040518060400160405280601881526020017f45524331313535423a20496e76616c696420616d6f756e74000000000000000081525081565b34801561065b57600080fd5b506105b96040518060400160405280601881526020017f45524331313535423a204e6f7420617574686f72697a6564000000000000000081525081565b3480156106a457600080fd5b506105b96113b3565b3480156106b957600080fd5b506105b96106c8366004613c95565b6113cf565b3480156106d957600080fd5b5061056161464f81565b3480156106ef57600080fd5b506105616114c7565b34801561070457600080fd5b5061072c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161056b565b34801561075057600080fd5b506105b9611508565b34801561076557600080fd5b506105617f000000000000000000000000000000000000000000000000000000000000000081565b34801561079957600080fd5b50610561656022099fa74481565b3480156107b357600080fd5b506105616107c2366004613cae565b6146526020526000908152604090205481565b3480156107e157600080fd5b506105b9611524565b3480156107f657600080fd5b506146575460201c610561565b34801561080f57600080fd5b5061060461081e366004613d57565b611540565b34801561082f57600080fd5b5061056161465081565b34801561084557600080fd5b5061056161177081565b34801561085b57600080fd5b50610604611a19565b610604611a50565b34801561087857600080fd5b50610561610887366004613cae565b611bf0565b34801561089857600080fd5b506105b9611d01565b610604611d1d565b3480156108b557600080fd5b506105b96040518060400160405280601a81526020017f506c61796572486f7573696e673a2057726f6e6720707269636500000000000081525081565b3480156108fe57600080fd5b5061091261090d366004613e12565b611e1b565b60405161056b9190613eb9565b34801561092b57600080fd5b506105b96040518060400160405280601781526020017f45524331313535423a204944206e6f74206d696e74656400000000000000000081525081565b610604610976366004613c69565b611f39565b34801561098757600080fd5b506105b9612216565b34801561099c57600080fd5b506106046109ab366004613ecc565b6122a5565b3480156109bc57600080fd5b506105b96040518060400160405280601e81526020017f45524331313535423a2046726f6d206e6f7420746f6b656e206f776e6572000081525081565b348015610a0557600080fd5b506105617f000000000000000000000000000000000000000000000000000000000000000081565b348015610a3957600080fd5b5061072c610a48366004613c95565b6122bf565b348015610a5957600080fd5b506105b96122e0565b348015610a6e57600080fd5b506105b96122fc565b348015610a8357600080fd5b50610561610a92366004613cae565b6001600160a01b03166000908152614652602052604090205461ffff1690565b348015610abe57600080fd5b5061060461230a565b348015610ad357600080fd5b506105b96040518060400160405280601a81526020017f45524331313535423a20556e7361666520726563697069656e7400000000000081525081565b348015610b1c57600080fd5b506105617f000000000000000000000000000000000000000000000000000000000000000081565b348015610b5057600080fd5b506146575461ffff16610561565b348015610b6a57600080fd5b50610604610b79366004613ecc565b61231c565b348015610b8a57600080fd5b506105b96040518060400160405280601481526020017f45524331313535423a20496e76616c696420494400000000000000000000000081525081565b348015610bd357600080fd5b506105b96040518060400160405280601a81526020017f506c61796572486f7573696e673a204e6f206d6574616461746100000000000081525081565b348015610c1c57600080fd5b506105b9612331565b348015610c3157600080fd5b50614651546001600160a01b031661072c565b61060461234d565b348015610c5857600080fd5b50610604610c67366004613b70565b6124eb565b348015610c7857600080fd5b506105b9612558565b610604612574565b348015610c9557600080fd5b506105b96040518060400160405280601b81526020017f45524331313535423a20494420616c7265616479206d696e746564000000000081525081565b348015610cde57600080fd5b50610604610ced366004613f1c565b612672565b348015610cfe57600080fd5b50610604610d0d366004613f53565b6126fd565b348015610d1e57600080fd5b50610604610d2d366004613cae565b6127c1565b348015610d3e57600080fd5b506146545461072c906001600160a01b031681565b348015610d5f57600080fd5b50610d686127d2565b60405161056b9190614003565b61060461281a565b348015610d8957600080fd5b506105b96129b8565b6106046129d4565b348015610da657600080fd5b5061056167016345785d8a000081565b348015610dc257600080fd5b506105b96040518060400160405280601681526020017f45524331313535423a20496e76616c69642066726f6d0000000000000000000081525081565b348015610e0b57600080fd5b50610604610e1a366004613f1c565b612ad2565b348015610e2b57600080fd5b506105b96040518060400160405280601b81526020017f45524331313535423a20496e76616c696420726563697069656e74000000000081525081565b348015610e7457600080fd5b506105b96040518060400160405280601b81526020017f506c61796572486f7573696e673a20546f6b656e206c6f636b6564000000000081525081565b348015610ebd57600080fd5b506105616146575460101c61ffff1690565b348015610edb57600080fd5b50610594610eea366004613cae565b6146536020526000908152604090205460ff1681565b348015610f0c57600080fd5b50610604610f1b366004613cae565b612b58565b348015610f2c57600080fd5b506105b9612bd6565b348015610f4157600080fd5b50610594610f50366004614040565b61465060209081526000928352604080842090915290825290205460ff1681565b348015610f7d57600080fd5b50610561600081565b348015610f9257600080fd5b506105b9612bf2565b348015610fa757600080fd5b506105b9612c0e565b348015610fbc57600080fd5b50610604610fcb366004614073565b612c2a565b348015610fdc57600080fd5b50610604610feb366004613cae565b613098565b348015610ffc57600080fd5b506105b96040518060400160405280601f81526020017f45524331313535423a204172726179206c656e677468206d69736d617463680081525081565b6000806000836146508110611050576110506140eb565b01546001600160a01b0316939093149392505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614806110f957507fd9b67a26000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b8061114557507f0e89341c000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6040518060600160405280602b8152602001614684602b913981565b6040805160608101909152602280825233321491906146056020830139906111ab5760405162461bcd60e51b81526004016111a29190613c18565b60405180910390fd5b507f00000000000000000000000000000000000000000000000000000000000000004210156040518060600160405280602481526020016146af60249139906112075760405162461bcd60e51b81526004016111a29190613c18565b5060058311156040518060600160405280602d8152602001614657602d9139906112445760405162461bcd60e51b81526004016111a29190613c18565b50600582111560405180606001604052806031815260200161474660319139906112815760405162461bcd60e51b81526004016111a29190613c18565b5060058111156040518060600160405280603481526020016145d160349139906112be5760405162461bcd60e51b81526004016111a29190613c18565b5060008183850101905060058111156040518060600160405280602b8152602001614684602b9139906113045760405162461bcd60e51b81526004016111a29190613c18565b50600181116040518060600160405280602381526020016146d360239139906113405760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a000083021461139f5760405162461bcd60e51b81526004016111a29190613c18565b506113ad3385858585613125565b50505050565b6040518060600160405280602481526020016146af6024913981565b6060600061465580546113e19061411a565b9050116040518060400160405280601a81526020017f506c61796572486f7573696e673a204e6f206d65746164617461000000000000815250906114385760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601481527f45524331313535423a20496e76616c69642049440000000000000000000000006020820152614650831061148f5760405162461bcd60e51b81526004016111a29190613c18565b5061465561149c8361342a565b6146566040516020016114b193929190614237565b6040516020818303038152906040529050919050565b60006114d66146575460201c90565b6114e76146575460101c61ffff1690565b6146575461ffff166114f99190614299565b6115039190614299565b905090565b6040518060600160405280602281526020016146056022913981565b6040518060600160405280602781526020016147776027913981565b60408051808201909152601f81527f45524331313535423a204172726179206c656e677468206d69736d617463680060208201528584146115945760405162461bcd60e51b81526004016111a29190613c18565b50336001600160a01b03891614806115d057506001600160a01b03881660009081526146506020908152604080832033845290915290205460ff165b6040518060400160405280601881526020017f45524331313535423a204e6f7420617574686f72697a65640000000000000000815250906116245760405162461bcd60e51b81526004016111a29190613c18565b50614654546040517fc2d638ef0000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063c2d638ef9061167990309033908d908d908d908d90600401614300565b6020604051808303816000875af1158015611698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bc9190614349565b156040518060400160405280601b81526020017f506c61796572486f7573696e673a20546f6b656e206c6f636b65640000000000815250906117115760405162461bcd60e51b81526004016111a29190613c18565b506020850260005b81811015611827578088013561464f8111156117745760405162461bcd60e51b815260206004820152601460248201527f45524331313535423a20496e76616c69642049440000000000000000000000006044820152606481fd5b868201356001146117c45760405162461bcd60e51b815260206004820152601860248201527f45524331313535423a20496e76616c696420616d6f756e7400000000000000006044820152606481fd5b80546001600160a01b03168b811461181b5760405162461bcd60e51b815260206004820152601e60248201527f45524331313535423a2046726f6d206e6f7420746f6b656e206f776e657200006044820152606481fd5b50899055602001611719565b506118359050888887613567565b866001600160a01b0316886001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb898989896040516118889493929190614366565b60405180910390a46001600160a01b0387163b156119b2576040517fbc197c8100000000000000000000000000000000000000000000000000000000808252906001600160a01b0389169063bc197c81906118f59033908d908c908c908c908c908c908c906004016143d6565b6020604051808303816000875af1158015611914573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611938919061443a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146040518060400160405280601a81526020017f45524331313535423a20556e7361666520726563697069656e74000000000000815250906119ac5760405162461bcd60e51b81526004016111a29190613c18565b50611a0f565b60408051808201909152601b81527f45524331313535423a20496e76616c696420726563697069656e74000000000060208201526001600160a01b038816611a0d5760405162461bcd60e51b81526004016111a29190613c18565b505b5050505050505050565b611a2161370f565b60405133904780156108fc02916000818181858888f19350505050158015611a4d573d6000803e3d6000fd5b50565b604080516060810190915260228082523332149190614605602083013990611a8b5760405162461bcd60e51b81526004016111a29190613c18565b507f00000000000000000000000000000000000000000000000000000000000000004210156040518060600160405280602781526020016147776027913990611ae75760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a000014611b445760405162461bcd60e51b81526004016111a29190613c18565b506040517ff5298aca00000000000000000000000000000000000000000000000000000000815233600482015260006024820152600160448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5298aca90606401600060405180830381600087803b158015611bcd57600080fd5b505af1158015611be1573d6000803e3d6000fd5b50505050611bee3361376a565b565b6001600160a01b03811660009081526146526020526040902054603081901c9060101c63ffffffff167f00000000000000000000000000000000000000000000000000000000000000008114611cfb5760007f00000000000000000000000000000000000000000000000000000000000000004210611c8f577f0000000000000000000000000000000000000000000000000000000000000000611c91565b425b90506000611cb9856001600160a01b03166000908152614652602052604090205461ffff1690565b90508215611cf8576000611ccd8484614457565b905081611ce0656022099fa7448361446e565b611cea919061446e565b611cf49086614299565b9450505b50505b50919050565b6040518060600160405280602781526020016146f66027913981565b604080516060810190915260228082523332149190614605602083013990611d585760405162461bcd60e51b81526004016111a29190613c18565b507f00000000000000000000000000000000000000000000000000000000000000004210156040518060600160405280602481526020016146af6024913990611db45760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a000014611e115760405162461bcd60e51b81526004016111a29190613c18565b50611bee3361384a565b60408051808201909152601f81527f45524331313535423a204172726179206c656e677468206d69736d61746368006020820152606090848314611e725760405162461bcd60e51b81526004016111a29190613c18565b508367ffffffffffffffff811115611e8c57611e8c6144ab565b604051908082528060200260200182016040528015611eb5578160200160208202803683370190505b50905060005b84811015611f3057611f0b868683818110611ed857611ed86140eb565b9050602002016020810190611eed9190613cae565b858584818110611eff57611eff6140eb565b90506020020135611039565b828281518110611f1d57611f1d6140eb565b6020908102919091010152600101611ebb565b50949350505050565b604080516060810190915260228082523332149190614605602083013990611f745760405162461bcd60e51b81526004016111a29190613c18565b507f00000000000000000000000000000000000000000000000000000000000000004210156040518060600160405280602781526020016147776027913990611fd05760405162461bcd60e51b81526004016111a29190613c18565b5060058311156040518060600160405280602d8152602001614657602d91399061200d5760405162461bcd60e51b81526004016111a29190613c18565b506005821115604051806060016040528060318152602001614746603191399061204a5760405162461bcd60e51b81526004016111a29190613c18565b5060058111156040518060600160405280603481526020016145d160349139906120875760405162461bcd60e51b81526004016111a29190613c18565b5060008183850101905060058111156040518060600160405280602b8152602001614684602b9139906120cd5760405162461bcd60e51b81526004016111a29190613c18565b50600181116040518060600160405280602381526020016146d360239139906121095760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a00008302146121685760405162461bcd60e51b81526004016111a29190613c18565b506040517ff5298aca00000000000000000000000000000000000000000000000000000000815233600482015260006024820152604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5298aca90606401600060405180830381600087803b1580156121f157600080fd5b505af1158015612205573d6000803e3d6000fd5b505050506113ad3385858585613125565b61465680546122249061411a565b80601f01602080910402602001604051908101604052809291908181526020018280546122509061411a565b801561229d5780601f106122725761010080835404028352916020019161229d565b820191906000526020600020905b81548152906001019060200180831161228057829003601f168201915b505050505081565b6122ad61370f565b6122ba6146558383613a7c565b505050565b60008161465081106122d057600080fd5b01546001600160a01b0316905081565b6040518060600160405280602d8152602001614657602d913981565b61465580546122249061411a565b61231261370f565b611bee60006138d8565b61232461370f565b6122ba6146568383613a7c565b60405180606001604052806029815260200161471d6029913981565b6040805160608101909152602280825233321491906146056020830139906123885760405162461bcd60e51b81526004016111a29190613c18565b507f000000000000000000000000000000000000000000000000000000000000000042101560405180606001604052806027815260200161477760279139906123e45760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a0000146124415760405162461bcd60e51b81526004016111a29190613c18565b506040517ff5298aca00000000000000000000000000000000000000000000000000000000815233600482015260006024820152600160448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5298aca90606401600060405180830381600087803b1580156124ca57600080fd5b505af11580156124de573d6000803e3d6000fd5b50505050611bee3361384a565b336000908152614653602090815260409182902054825160608101909352602780845260ff90911692916146f6908301399061253a5760405162461bcd60e51b81526004016111a29190613c18565b506001600160a01b0390911660009081526146526020526040902055565b6040518060600160405280602381526020016146d36023913981565b6040805160608101909152602280825233321491906146056020830139906125af5760405162461bcd60e51b81526004016111a29190613c18565b507f00000000000000000000000000000000000000000000000000000000000000004210156040518060600160405280602481526020016146af602491399061260b5760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a0000146126685760405162461bcd60e51b81526004016111a29190613c18565b50611bee3361376a565b336000818152614650602090815260408083206001600160a01b0387168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61270561370f565b868514801561271357508483145b801561271e57508281145b6040518060400160405280601f81526020017f45524331313535423a204172726179206c656e677468206d69736d6174636800815250906127725760405162461bcd60e51b81526004016111a29190613c18565b506020870260005b818110156127b55760208101908a810135908981013590888101359087013581830181016127ab8585858585613125565b505050505061277a565b50505050505050505050565b6127c961370f565b611a4d8161384a565b6127da613b1e565b604080516208ca00810191829052906000906146509082845b81546001600160a01b031681526001909101906020018083116127f3575050505050905090565b6040805160608101909152602280825233321491906146056020830139906128555760405162461bcd60e51b81526004016111a29190613c18565b507f000000000000000000000000000000000000000000000000000000000000000042101560405180606001604052806027815260200161477760279139906128b15760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a00001461290e5760405162461bcd60e51b81526004016111a29190613c18565b506040517ff5298aca00000000000000000000000000000000000000000000000000000000815233600482015260006024820152600160448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5298aca90606401600060405180830381600087803b15801561299757600080fd5b505af11580156129ab573d6000803e3d6000fd5b50505050611bee33613943565b6040518060600160405280603181526020016147466031913981565b604080516060810190915260228082523332149190614605602083013990612a0f5760405162461bcd60e51b81526004016111a29190613c18565b507f00000000000000000000000000000000000000000000000000000000000000004210156040518060600160405280602481526020016146af6024913990612a6b5760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a000014612ac85760405162461bcd60e51b81526004016111a29190613c18565b50611bee33613943565b612ada61370f565b6001600160a01b0382166000818152614653602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f7b708b778140a177a5a50654ade8c6bef195eb041b31c374ae3e9d82e0de9233910160405180910390a25050565b612b6061370f565b614654546040516001600160a01b038084169216907f606d63a4236a3485ccb92cec46cd7387dac870c31434cd4f8ab856020c78598c90600090a361465480547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6040518060600160405280603081526020016146276030913981565b6040518060600160405280603481526020016145d16034913981565b6040518060600160405280602d815260200161479e602d913981565b336001600160a01b0387161480612c6557506001600160a01b03861660009081526146506020908152604080832033845290915290205460ff165b6040518060400160405280601881526020017f45524331313535423a204e6f7420617574686f72697a6564000000000000000081525090612cb95760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601481527f45524331313535423a20496e76616c696420494400000000000000000000000060208201526146508510612d105760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601881527f45524331313535423a20496e76616c696420616d6f756e740000000000000000602082015260018414612d665760405162461bcd60e51b81526004016111a29190613c18565b50614654546040517fcbc3fb560000000000000000000000000000000000000000000000000000000081523060048201523360248201526001600160a01b0388811660448301528781166064830152608482018790529091169063cbc3fb569060a4016020604051808303816000875af1158015612de8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e0c9190614349565b156040518060400160405280601b81526020017f506c61796572486f7573696e673a20546f6b656e206c6f636b6564000000000081525090612e615760405162461bcd60e51b81526004016111a29190613c18565b50835484906001600160a01b0316878114612ebb5760405162461bcd60e51b815260206004820152601e60248201527f45524331313535423a2046726f6d206e6f7420746f6b656e206f776e657200006044820152606481fd5b50859055612eca868685613567565b60408051858152602081018590526001600160a01b03808816929089169133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46001600160a01b0385163b15613033576040517ff23a6e6100000000000000000000000000000000000000000000000000000000808252906001600160a01b0387169063f23a6e6190612f769033908b908a908a908a908a906004016144da565b6020604051808303816000875af1158015612f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fb9919061443a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146040518060400160405280601a81526020017f45524331313535423a20556e7361666520726563697069656e740000000000008152509061302d5760405162461bcd60e51b81526004016111a29190613c18565b50613090565b60408051808201909152601b81527f45524331313535423a20496e76616c696420726563697069656e74000000000060208201526001600160a01b03861661308e5760405162461bcd60e51b81526004016111a29190613c18565b505b505050505050565b6130a061370f565b6001600160a01b03811661311c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016111a2565b611a4d816138d8565b60008167ffffffffffffffff811115613140576131406144ab565b604051908082528060200260200182016040528015613169578160200160208202803683370190505b50905060008267ffffffffffffffff811115613187576131876144ab565b6040519080825280602002602001820160405280156131b0578160200160208202803683370190505b506146575490915060208381019190830190808915613263576040805160608101909152602980825261ffff8416918c830191611770831115919061471d6020830139906132115760405162461bcd60e51b81526004016111a29190613c18565b50815b81811015613237578d815580875260018087526020978801979096019501613214565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009290921690911790505b881561330f576040805160608101909152602d808252601084901c61ffff16918b830191611770831115919061479e6020830139906132b55760405162461bcd60e51b81526004016111a29190613c18565b50815b818110156132df5761177081018e81558752600180875260209788019790960195016132b8565b5060101b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff929092169190911790505b87156133b55760408051606081019091526030808252602084811c928b84019261177084111592614627908301399061335b5760405162461bcd60e51b81526004016111a29190613c18565b50815b8181101561338557612ee081018e815587526001808752602097880197909601950161335e565b5060201b7fffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff929092169190911790505b6146578190556133c58b886139f6565b8a6001600160a01b031660006001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8989604051613415929190614513565b60405180910390a45050505050505050505050565b60608160000361346d57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115613497578061348181614541565b91506134909050600a836145a8565b9150613471565b60008167ffffffffffffffff8111156134b2576134b26144ab565b6040519080825280601f01601f1916602001820160405280156134dc576020820181803683370190505b5090505b841561355f576134f1600183614457565b91506134fe600a866145bc565b613509906030614299565b60f81b81838151811061351e5761351e6140eb565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350613558600a866145a8565b94506134e0565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000042106135b6577f00000000000000000000000000000000000000000000000000000000000000006135b8565b425b6001600160a01b03851660009081526146526020526040902054909150601081901c63ffffffff167f000000000000000000000000000000000000000000000000000000000000000081146136615761ffff8216603083901c82156136345760006136238487614457565b8302656022099fa744029190910190505b6001600160a01b03881660009081526146526020526040902091869003601086901b1760309190911b1790555b50506001600160a01b03831660009081526146526020526040902054601081901c63ffffffff167f000000000000000000000000000000000000000000000000000000000000000081146130905761ffff8216603083901c82156136dc5760006136cb8487614457565b8302656022099fa744029190910190505b6001600160a01b038716600090815261465260205260409020918601601086901b1760309190911b179055505050505050565b614651546001600160a01b03163314611bee5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016111a2565b614657546040805160608101909152602d808252601083901c61ffff169161177083109161479e6020830139906137b45760405162461bcd60e51b81526004016111a29190613c18565b5061177081018381556001918201601081901b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff85161761465755916137fb9085906139f6565b60408051828152600160208201526001600160a01b0386169160009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a450505050565b6146575460408051606081019091526030808252602083811c92611770841092909161462790830139906138915760405162461bcd60e51b81526004016111a29190613c18565b50612ee081018381556001918201602081901b7fffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff85161761465755916137fb9085906139f6565b61465180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600061ffff801661465754169050611770811060405180606001604052806029815260200161471d602991399061398d5760405162461bcd60e51b81526004016111a29190613c18565b50818155614657805460019081019091556139a99083906139f6565b60408051828152600160208201526001600160a01b0384169160009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a45050565b6001600160a01b0382166000908152614652602052604090205461ffff8116601082901c63ffffffff16603083901c8115613a48576000613a378342614457565b8402656022099fa744029190910190505b6001600160a01b03909516600090815261465260205260409020919093014260101b1760309490941b939093179092555050565b828054613a889061411a565b90600052602060002090601f016020900481019282613aaa5760008555613b0e565b82601f10613ae1578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555613b0e565b82800160010185558215613b0e579182015b82811115613b0e578235825591602001919060010190613af3565b50613b1a929150613b3f565b5090565b604051806208ca000160405280614650906020820280368337509192915050565b5b80821115613b1a5760008155600101613b40565b80356001600160a01b0381168114613b6b57600080fd5b919050565b60008060408385031215613b8357600080fd5b613b8c83613b54565b946020939093013593505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611a4d57600080fd5b600060208284031215613bda57600080fd5b8135613be581613b9a565b9392505050565b60005b83811015613c07578181015183820152602001613bef565b838111156113ad5750506000910152565b6020815260008251806020840152613c37816040850160208701613bec565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600080600060608486031215613c7e57600080fd5b505081359360208301359350604090920135919050565b600060208284031215613ca757600080fd5b5035919050565b600060208284031215613cc057600080fd5b613be582613b54565b60008083601f840112613cdb57600080fd5b50813567ffffffffffffffff811115613cf357600080fd5b6020830191508360208260051b8501011115613d0e57600080fd5b9250929050565b60008083601f840112613d2757600080fd5b50813567ffffffffffffffff811115613d3f57600080fd5b602083019150836020828501011115613d0e57600080fd5b60008060008060008060008060a0898b031215613d7357600080fd5b613d7c89613b54565b9750613d8a60208a01613b54565b9650604089013567ffffffffffffffff80821115613da757600080fd5b613db38c838d01613cc9565b909850965060608b0135915080821115613dcc57600080fd5b613dd88c838d01613cc9565b909650945060808b0135915080821115613df157600080fd5b50613dfe8b828c01613d15565b999c989b5096995094979396929594505050565b60008060008060408587031215613e2857600080fd5b843567ffffffffffffffff80821115613e4057600080fd5b613e4c88838901613cc9565b90965094506020870135915080821115613e6557600080fd5b50613e7287828801613cc9565b95989497509550505050565b600081518084526020808501945080840160005b83811015613eae57815187529582019590820190600101613e92565b509495945050505050565b602081526000613be56020830184613e7e565b60008060208385031215613edf57600080fd5b823567ffffffffffffffff811115613ef657600080fd5b613f0285828601613d15565b90969095509350505050565b8015158114611a4d57600080fd5b60008060408385031215613f2f57600080fd5b613f3883613b54565b91506020830135613f4881613f0e565b809150509250929050565b6000806000806000806000806080898b031215613f6f57600080fd5b883567ffffffffffffffff80821115613f8757600080fd5b613f938c838d01613cc9565b909a50985060208b0135915080821115613fac57600080fd5b613fb88c838d01613cc9565b909850965060408b0135915080821115613fd157600080fd5b613fdd8c838d01613cc9565b909650945060608b0135915080821115613ff657600080fd5b50613dfe8b828c01613cc9565b6208ca008101818360005b6146508110156140375781516001600160a01b031683526020928301929091019060010161400e565b50505092915050565b6000806040838503121561405357600080fd5b61405c83613b54565b915061406a60208401613b54565b90509250929050565b60008060008060008060a0878903121561408c57600080fd5b61409587613b54565b95506140a360208801613b54565b94506040870135935060608701359250608087013567ffffffffffffffff8111156140cd57600080fd5b6140d989828a01613d15565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061412e57607f821691505b602082108103611cfb577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b8054600090600181811c908083168061418157607f831692505b602080841082036141bb577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b8180156141cf57600181146141fe5761422b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0086168952848901965061422b565b60008881526020902060005b868110156142235781548b82015290850190830161420a565b505084890196505b50505050505092915050565b60006142438286614167565b8451614253818360208901613bec565b61425f81830186614167565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156142ac576142ac61426a565b500190565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156142e357600080fd5b8260051b8083602087013760009401602001938452509192915050565b60006001600160a01b0380891683528088166020840152808716604084015280861660608401525060a0608083015261433d60a0830184866142b1565b98975050505050505050565b60006020828403121561435b57600080fd5b8151613be581613f0e565b60408152600061437a6040830186886142b1565b828103602084015261425f8185876142b1565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60006001600160a01b03808b168352808a1660208401525060a0604083015261440360a08301888a6142b1565b82810360608401526144168187896142b1565b9050828103608084015261442b81858761438d565b9b9a5050505050505050505050565b60006020828403121561444c57600080fd5b8151613be581613b9a565b6000828210156144695761446961426a565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156144a6576144a661426a565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006001600160a01b03808916835280881660208401525085604083015284606083015260a0608083015261433d60a08301848661438d565b6040815260006145266040830185613e7e565b82810360208401526145388185613e7e565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145725761457261426a565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826145b7576145b7614579565b500490565b6000826145cb576145cb614579565b50069056fe506c61796572486f7573696e673a204c61637265616e20456d70697265206f766572206d617820616d6f756e7420706572207478506c61796572486f7573696e673a204e6f20636f6e7472616374206d696e74696e67506c61796572486f7573696e673a2052656163686564206d6178204c61637265616e20456d7069726520737570706c79506c61796572486f7573696e673a204172626f726961206f766572206d617820616d6f756e7420706572207478506c61796572486f7573696e673a20546f74616c206f766572206d617820616d6f756e7420706572207478506c61796572486f7573696e673a205075626c69632073616c65206e6f74207265616479506c61796572486f7573696e673a20546f74616c20616d6f756e742062656c6f772032506c61796572486f7573696e673a204e6f7420617070726f76656420666f722072657761726473506c61796572486f7573696e673a2052656163686564206d6178204172626f72696120737570706c79506c61796572486f7573696e673a20496c6c736b616761617264206f766572206d617820616d6f756e7420706572207478506c61796572486f7573696e673a2057686974656c6973742073616c65206e6f74207265616479506c61796572486f7573696e673a2052656163686564206d617820496c6c736b61676161726420737570706c79a2646970667358221220ab14a4c15a796cfa7eaba33e0bae8b63ce81e69700e041524da59d7937d7a8b164736f6c634300080e00330000000000000000000000005a5fe90cd115d691ee99d90d3607f7005ea817e50000000000000000000000000000000000000000000000000000000062dae5a00000000000000000000000000000000000000000000000000000000062dd88a00000000000000000000000000000000000000000000000000000000075a6e8a0000000000000000000000000544d219c227856935bf9678e21a2cd012bcc8bd8000000000000000000000000616e6b2ba922968af8d46df9400fc3da17589c5f
Deployed Bytecode
0x60806040526004361061053c5760003560e01c806370a08231116102af578063affe39c111610179578063dd74d3b7116100d6578063efd52b8b1161008a578063f242432a1161006f578063f242432a14610fb0578063f2fde38b14610fd0578063f806b10114610ff057600080fd5b8063efd52b8b14610f86578063f1d91b1214610f9b57600080fd5b8063e4a1ada4116100bb578063e4a1ada414610f20578063e985e9c514610f35578063ea39260014610f7157600080fd5b8063dd74d3b714610ecf578063deedfdbd14610f0057600080fd5b8063c1049e801161012d578063c8d3403911610112578063c8d3403914610e1f578063d39fbaa414610e68578063dbcfd08f14610eb157600080fd5b8063c1049e8014610db6578063c64a0b8b14610dff57600080fd5b8063bdb6fe2a1161015e578063bdb6fe2a14610d7d578063bfd7253f14610d92578063c002d23d14610d9a57600080fd5b8063affe39c114610d53578063b9be77b214610d7557600080fd5b80638da5cb5b11610227578063a113152b116101db578063a42bfe6d116101c0578063a42bfe6d14610cf2578063a4a4003814610d12578063acca30a214610d3257600080fd5b8063a113152b14610c89578063a22cb46514610cd257600080fd5b80639030d1bb1161020c5780639030d1bb14610c4c57806398c7798414610c6c578063a0afde1514610c8157600080fd5b80638da5cb5b14610c255780638f13c2a414610c4457600080fd5b8063802e79181161027e57806386aaf9341161026357806386aaf93414610b7e578063873b4aa914610bc7578063878de91e14610c1057600080fd5b8063802e791814610b4457806381b3e57514610b5e57600080fd5b806370a0823114610a77578063715018a614610ab25780637999567114610ac75780637aeb357314610b1057600080fd5b80632eb2c2d61161040b5780634ee6262d11610368578063576793491161031c5780636352211e116103015780636352211e14610a2d5780636a01be5314610a4d5780636c0360eb14610a6257600080fd5b806357679349146109b057806358e96d5f146109f957600080fd5b806351f977041161034d57806351f97704146109685780635503a0e81461097b57806355f804b31461099057600080fd5b80634ee6262d1461091f5780634f9bba2c1461083957600080fd5b8063479ba7ae116103bf5780634d58026c116103a45780634d58026c146108a15780634d7e41d5146108a95780634e1273f4146108f257600080fd5b8063479ba7ae1461086c5780634c09e3e61461088c57600080fd5b806335f743ae116103f057806335f743ae146108395780633ccfd60b1461084f5780633e4af9c51461086457600080fd5b80632eb2c2d61461080357806332cb6b0c1461082357600080fd5b80630e89341c116104b95780631adc62d81161046d578063207e3cc311610452578063207e3cc3146107a75780632552a1d0146107d55780632d960a4c146107ea57600080fd5b80631adc62d8146107595780631d84cee91461078d57600080fd5b806318160ddd1161049e57806318160ddd146106e357806318c33e46146106f8578063192d4df61461074457600080fd5b80630e89341c146106ad57806317bac052146106cd57600080fd5b80630ae349f4116105105780630d6f23cd116104f55780630d6f23cd146106065780630df1f7c71461064f5780630e0847211461069857600080fd5b80630ae349f4146105db5780630b32f0b2146105f157600080fd5b8062fdd58e1461054157806301ffc9a71461057457806303e56262146105a457806309ef6527146105c6575b600080fd5b34801561054d57600080fd5b5061056161055c366004613b70565b611039565b6040519081526020015b60405180910390f35b34801561058057600080fd5b5061059461058f366004613bc8565b611066565b604051901515815260200161056b565b3480156105b057600080fd5b506105b961114b565b60405161056b9190613c18565b3480156105d257600080fd5b50610561600581565b3480156105e757600080fd5b50610561612ee081565b6106046105ff366004613c69565b611167565b005b34801561061257600080fd5b506105b96040518060400160405280601881526020017f45524331313535423a20496e76616c696420616d6f756e74000000000000000081525081565b34801561065b57600080fd5b506105b96040518060400160405280601881526020017f45524331313535423a204e6f7420617574686f72697a6564000000000000000081525081565b3480156106a457600080fd5b506105b96113b3565b3480156106b957600080fd5b506105b96106c8366004613c95565b6113cf565b3480156106d957600080fd5b5061056161464f81565b3480156106ef57600080fd5b506105616114c7565b34801561070457600080fd5b5061072c7f000000000000000000000000544d219c227856935bf9678e21a2cd012bcc8bd881565b6040516001600160a01b03909116815260200161056b565b34801561075057600080fd5b506105b9611508565b34801561076557600080fd5b506105617f0000000000000000000000000000000000000000000000000000000062dd88a081565b34801561079957600080fd5b50610561656022099fa74481565b3480156107b357600080fd5b506105616107c2366004613cae565b6146526020526000908152604090205481565b3480156107e157600080fd5b506105b9611524565b3480156107f657600080fd5b506146575460201c610561565b34801561080f57600080fd5b5061060461081e366004613d57565b611540565b34801561082f57600080fd5b5061056161465081565b34801561084557600080fd5b5061056161177081565b34801561085b57600080fd5b50610604611a19565b610604611a50565b34801561087857600080fd5b50610561610887366004613cae565b611bf0565b34801561089857600080fd5b506105b9611d01565b610604611d1d565b3480156108b557600080fd5b506105b96040518060400160405280601a81526020017f506c61796572486f7573696e673a2057726f6e6720707269636500000000000081525081565b3480156108fe57600080fd5b5061091261090d366004613e12565b611e1b565b60405161056b9190613eb9565b34801561092b57600080fd5b506105b96040518060400160405280601781526020017f45524331313535423a204944206e6f74206d696e74656400000000000000000081525081565b610604610976366004613c69565b611f39565b34801561098757600080fd5b506105b9612216565b34801561099c57600080fd5b506106046109ab366004613ecc565b6122a5565b3480156109bc57600080fd5b506105b96040518060400160405280601e81526020017f45524331313535423a2046726f6d206e6f7420746f6b656e206f776e6572000081525081565b348015610a0557600080fd5b506105617f0000000000000000000000000000000000000000000000000000000062dae5a081565b348015610a3957600080fd5b5061072c610a48366004613c95565b6122bf565b348015610a5957600080fd5b506105b96122e0565b348015610a6e57600080fd5b506105b96122fc565b348015610a8357600080fd5b50610561610a92366004613cae565b6001600160a01b03166000908152614652602052604090205461ffff1690565b348015610abe57600080fd5b5061060461230a565b348015610ad357600080fd5b506105b96040518060400160405280601a81526020017f45524331313535423a20556e7361666520726563697069656e7400000000000081525081565b348015610b1c57600080fd5b506105617f0000000000000000000000000000000000000000000000000000000075a6e8a081565b348015610b5057600080fd5b506146575461ffff16610561565b348015610b6a57600080fd5b50610604610b79366004613ecc565b61231c565b348015610b8a57600080fd5b506105b96040518060400160405280601481526020017f45524331313535423a20496e76616c696420494400000000000000000000000081525081565b348015610bd357600080fd5b506105b96040518060400160405280601a81526020017f506c61796572486f7573696e673a204e6f206d6574616461746100000000000081525081565b348015610c1c57600080fd5b506105b9612331565b348015610c3157600080fd5b50614651546001600160a01b031661072c565b61060461234d565b348015610c5857600080fd5b50610604610c67366004613b70565b6124eb565b348015610c7857600080fd5b506105b9612558565b610604612574565b348015610c9557600080fd5b506105b96040518060400160405280601b81526020017f45524331313535423a20494420616c7265616479206d696e746564000000000081525081565b348015610cde57600080fd5b50610604610ced366004613f1c565b612672565b348015610cfe57600080fd5b50610604610d0d366004613f53565b6126fd565b348015610d1e57600080fd5b50610604610d2d366004613cae565b6127c1565b348015610d3e57600080fd5b506146545461072c906001600160a01b031681565b348015610d5f57600080fd5b50610d686127d2565b60405161056b9190614003565b61060461281a565b348015610d8957600080fd5b506105b96129b8565b6106046129d4565b348015610da657600080fd5b5061056167016345785d8a000081565b348015610dc257600080fd5b506105b96040518060400160405280601681526020017f45524331313535423a20496e76616c69642066726f6d0000000000000000000081525081565b348015610e0b57600080fd5b50610604610e1a366004613f1c565b612ad2565b348015610e2b57600080fd5b506105b96040518060400160405280601b81526020017f45524331313535423a20496e76616c696420726563697069656e74000000000081525081565b348015610e7457600080fd5b506105b96040518060400160405280601b81526020017f506c61796572486f7573696e673a20546f6b656e206c6f636b6564000000000081525081565b348015610ebd57600080fd5b506105616146575460101c61ffff1690565b348015610edb57600080fd5b50610594610eea366004613cae565b6146536020526000908152604090205460ff1681565b348015610f0c57600080fd5b50610604610f1b366004613cae565b612b58565b348015610f2c57600080fd5b506105b9612bd6565b348015610f4157600080fd5b50610594610f50366004614040565b61465060209081526000928352604080842090915290825290205460ff1681565b348015610f7d57600080fd5b50610561600081565b348015610f9257600080fd5b506105b9612bf2565b348015610fa757600080fd5b506105b9612c0e565b348015610fbc57600080fd5b50610604610fcb366004614073565b612c2a565b348015610fdc57600080fd5b50610604610feb366004613cae565b613098565b348015610ffc57600080fd5b506105b96040518060400160405280601f81526020017f45524331313535423a204172726179206c656e677468206d69736d617463680081525081565b6000806000836146508110611050576110506140eb565b01546001600160a01b0316939093149392505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614806110f957507fd9b67a26000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b8061114557507f0e89341c000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6040518060600160405280602b8152602001614684602b913981565b6040805160608101909152602280825233321491906146056020830139906111ab5760405162461bcd60e51b81526004016111a29190613c18565b60405180910390fd5b507f0000000000000000000000000000000000000000000000000000000062dd88a04210156040518060600160405280602481526020016146af60249139906112075760405162461bcd60e51b81526004016111a29190613c18565b5060058311156040518060600160405280602d8152602001614657602d9139906112445760405162461bcd60e51b81526004016111a29190613c18565b50600582111560405180606001604052806031815260200161474660319139906112815760405162461bcd60e51b81526004016111a29190613c18565b5060058111156040518060600160405280603481526020016145d160349139906112be5760405162461bcd60e51b81526004016111a29190613c18565b5060008183850101905060058111156040518060600160405280602b8152602001614684602b9139906113045760405162461bcd60e51b81526004016111a29190613c18565b50600181116040518060600160405280602381526020016146d360239139906113405760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a000083021461139f5760405162461bcd60e51b81526004016111a29190613c18565b506113ad3385858585613125565b50505050565b6040518060600160405280602481526020016146af6024913981565b6060600061465580546113e19061411a565b9050116040518060400160405280601a81526020017f506c61796572486f7573696e673a204e6f206d65746164617461000000000000815250906114385760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601481527f45524331313535423a20496e76616c69642049440000000000000000000000006020820152614650831061148f5760405162461bcd60e51b81526004016111a29190613c18565b5061465561149c8361342a565b6146566040516020016114b193929190614237565b6040516020818303038152906040529050919050565b60006114d66146575460201c90565b6114e76146575460101c61ffff1690565b6146575461ffff166114f99190614299565b6115039190614299565b905090565b6040518060600160405280602281526020016146056022913981565b6040518060600160405280602781526020016147776027913981565b60408051808201909152601f81527f45524331313535423a204172726179206c656e677468206d69736d617463680060208201528584146115945760405162461bcd60e51b81526004016111a29190613c18565b50336001600160a01b03891614806115d057506001600160a01b03881660009081526146506020908152604080832033845290915290205460ff165b6040518060400160405280601881526020017f45524331313535423a204e6f7420617574686f72697a65640000000000000000815250906116245760405162461bcd60e51b81526004016111a29190613c18565b50614654546040517fc2d638ef0000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063c2d638ef9061167990309033908d908d908d908d90600401614300565b6020604051808303816000875af1158015611698573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bc9190614349565b156040518060400160405280601b81526020017f506c61796572486f7573696e673a20546f6b656e206c6f636b65640000000000815250906117115760405162461bcd60e51b81526004016111a29190613c18565b506020850260005b81811015611827578088013561464f8111156117745760405162461bcd60e51b815260206004820152601460248201527f45524331313535423a20496e76616c69642049440000000000000000000000006044820152606481fd5b868201356001146117c45760405162461bcd60e51b815260206004820152601860248201527f45524331313535423a20496e76616c696420616d6f756e7400000000000000006044820152606481fd5b80546001600160a01b03168b811461181b5760405162461bcd60e51b815260206004820152601e60248201527f45524331313535423a2046726f6d206e6f7420746f6b656e206f776e657200006044820152606481fd5b50899055602001611719565b506118359050888887613567565b866001600160a01b0316886001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb898989896040516118889493929190614366565b60405180910390a46001600160a01b0387163b156119b2576040517fbc197c8100000000000000000000000000000000000000000000000000000000808252906001600160a01b0389169063bc197c81906118f59033908d908c908c908c908c908c908c906004016143d6565b6020604051808303816000875af1158015611914573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611938919061443a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146040518060400160405280601a81526020017f45524331313535423a20556e7361666520726563697069656e74000000000000815250906119ac5760405162461bcd60e51b81526004016111a29190613c18565b50611a0f565b60408051808201909152601b81527f45524331313535423a20496e76616c696420726563697069656e74000000000060208201526001600160a01b038816611a0d5760405162461bcd60e51b81526004016111a29190613c18565b505b5050505050505050565b611a2161370f565b60405133904780156108fc02916000818181858888f19350505050158015611a4d573d6000803e3d6000fd5b50565b604080516060810190915260228082523332149190614605602083013990611a8b5760405162461bcd60e51b81526004016111a29190613c18565b507f0000000000000000000000000000000000000000000000000000000062dae5a04210156040518060600160405280602781526020016147776027913990611ae75760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a000014611b445760405162461bcd60e51b81526004016111a29190613c18565b506040517ff5298aca00000000000000000000000000000000000000000000000000000000815233600482015260006024820152600160448201527f000000000000000000000000544d219c227856935bf9678e21a2cd012bcc8bd86001600160a01b03169063f5298aca90606401600060405180830381600087803b158015611bcd57600080fd5b505af1158015611be1573d6000803e3d6000fd5b50505050611bee3361376a565b565b6001600160a01b03811660009081526146526020526040902054603081901c9060101c63ffffffff167f0000000000000000000000000000000000000000000000000000000075a6e8a08114611cfb5760007f0000000000000000000000000000000000000000000000000000000075a6e8a04210611c8f577f0000000000000000000000000000000000000000000000000000000075a6e8a0611c91565b425b90506000611cb9856001600160a01b03166000908152614652602052604090205461ffff1690565b90508215611cf8576000611ccd8484614457565b905081611ce0656022099fa7448361446e565b611cea919061446e565b611cf49086614299565b9450505b50505b50919050565b6040518060600160405280602781526020016146f66027913981565b604080516060810190915260228082523332149190614605602083013990611d585760405162461bcd60e51b81526004016111a29190613c18565b507f0000000000000000000000000000000000000000000000000000000062dd88a04210156040518060600160405280602481526020016146af6024913990611db45760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a000014611e115760405162461bcd60e51b81526004016111a29190613c18565b50611bee3361384a565b60408051808201909152601f81527f45524331313535423a204172726179206c656e677468206d69736d61746368006020820152606090848314611e725760405162461bcd60e51b81526004016111a29190613c18565b508367ffffffffffffffff811115611e8c57611e8c6144ab565b604051908082528060200260200182016040528015611eb5578160200160208202803683370190505b50905060005b84811015611f3057611f0b868683818110611ed857611ed86140eb565b9050602002016020810190611eed9190613cae565b858584818110611eff57611eff6140eb565b90506020020135611039565b828281518110611f1d57611f1d6140eb565b6020908102919091010152600101611ebb565b50949350505050565b604080516060810190915260228082523332149190614605602083013990611f745760405162461bcd60e51b81526004016111a29190613c18565b507f0000000000000000000000000000000000000000000000000000000062dae5a04210156040518060600160405280602781526020016147776027913990611fd05760405162461bcd60e51b81526004016111a29190613c18565b5060058311156040518060600160405280602d8152602001614657602d91399061200d5760405162461bcd60e51b81526004016111a29190613c18565b506005821115604051806060016040528060318152602001614746603191399061204a5760405162461bcd60e51b81526004016111a29190613c18565b5060058111156040518060600160405280603481526020016145d160349139906120875760405162461bcd60e51b81526004016111a29190613c18565b5060008183850101905060058111156040518060600160405280602b8152602001614684602b9139906120cd5760405162461bcd60e51b81526004016111a29190613c18565b50600181116040518060600160405280602381526020016146d360239139906121095760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a00008302146121685760405162461bcd60e51b81526004016111a29190613c18565b506040517ff5298aca00000000000000000000000000000000000000000000000000000000815233600482015260006024820152604481018290527f000000000000000000000000544d219c227856935bf9678e21a2cd012bcc8bd86001600160a01b03169063f5298aca90606401600060405180830381600087803b1580156121f157600080fd5b505af1158015612205573d6000803e3d6000fd5b505050506113ad3385858585613125565b61465680546122249061411a565b80601f01602080910402602001604051908101604052809291908181526020018280546122509061411a565b801561229d5780601f106122725761010080835404028352916020019161229d565b820191906000526020600020905b81548152906001019060200180831161228057829003601f168201915b505050505081565b6122ad61370f565b6122ba6146558383613a7c565b505050565b60008161465081106122d057600080fd5b01546001600160a01b0316905081565b6040518060600160405280602d8152602001614657602d913981565b61465580546122249061411a565b61231261370f565b611bee60006138d8565b61232461370f565b6122ba6146568383613a7c565b60405180606001604052806029815260200161471d6029913981565b6040805160608101909152602280825233321491906146056020830139906123885760405162461bcd60e51b81526004016111a29190613c18565b507f0000000000000000000000000000000000000000000000000000000062dae5a042101560405180606001604052806027815260200161477760279139906123e45760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a0000146124415760405162461bcd60e51b81526004016111a29190613c18565b506040517ff5298aca00000000000000000000000000000000000000000000000000000000815233600482015260006024820152600160448201527f000000000000000000000000544d219c227856935bf9678e21a2cd012bcc8bd86001600160a01b03169063f5298aca90606401600060405180830381600087803b1580156124ca57600080fd5b505af11580156124de573d6000803e3d6000fd5b50505050611bee3361384a565b336000908152614653602090815260409182902054825160608101909352602780845260ff90911692916146f6908301399061253a5760405162461bcd60e51b81526004016111a29190613c18565b506001600160a01b0390911660009081526146526020526040902055565b6040518060600160405280602381526020016146d36023913981565b6040805160608101909152602280825233321491906146056020830139906125af5760405162461bcd60e51b81526004016111a29190613c18565b507f0000000000000000000000000000000000000000000000000000000062dd88a04210156040518060600160405280602481526020016146af602491399061260b5760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a0000146126685760405162461bcd60e51b81526004016111a29190613c18565b50611bee3361376a565b336000818152614650602090815260408083206001600160a01b0387168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61270561370f565b868514801561271357508483145b801561271e57508281145b6040518060400160405280601f81526020017f45524331313535423a204172726179206c656e677468206d69736d6174636800815250906127725760405162461bcd60e51b81526004016111a29190613c18565b506020870260005b818110156127b55760208101908a810135908981013590888101359087013581830181016127ab8585858585613125565b505050505061277a565b50505050505050505050565b6127c961370f565b611a4d8161384a565b6127da613b1e565b604080516208ca00810191829052906000906146509082845b81546001600160a01b031681526001909101906020018083116127f3575050505050905090565b6040805160608101909152602280825233321491906146056020830139906128555760405162461bcd60e51b81526004016111a29190613c18565b507f0000000000000000000000000000000000000000000000000000000062dae5a042101560405180606001604052806027815260200161477760279139906128b15760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a00001461290e5760405162461bcd60e51b81526004016111a29190613c18565b506040517ff5298aca00000000000000000000000000000000000000000000000000000000815233600482015260006024820152600160448201527f000000000000000000000000544d219c227856935bf9678e21a2cd012bcc8bd86001600160a01b03169063f5298aca90606401600060405180830381600087803b15801561299757600080fd5b505af11580156129ab573d6000803e3d6000fd5b50505050611bee33613943565b6040518060600160405280603181526020016147466031913981565b604080516060810190915260228082523332149190614605602083013990612a0f5760405162461bcd60e51b81526004016111a29190613c18565b507f0000000000000000000000000000000000000000000000000000000062dd88a04210156040518060600160405280602481526020016146af6024913990612a6b5760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601a81527f506c61796572486f7573696e673a2057726f6e6720707269636500000000000060208201523467016345785d8a000014612ac85760405162461bcd60e51b81526004016111a29190613c18565b50611bee33613943565b612ada61370f565b6001600160a01b0382166000818152614653602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f7b708b778140a177a5a50654ade8c6bef195eb041b31c374ae3e9d82e0de9233910160405180910390a25050565b612b6061370f565b614654546040516001600160a01b038084169216907f606d63a4236a3485ccb92cec46cd7387dac870c31434cd4f8ab856020c78598c90600090a361465480547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6040518060600160405280603081526020016146276030913981565b6040518060600160405280603481526020016145d16034913981565b6040518060600160405280602d815260200161479e602d913981565b336001600160a01b0387161480612c6557506001600160a01b03861660009081526146506020908152604080832033845290915290205460ff165b6040518060400160405280601881526020017f45524331313535423a204e6f7420617574686f72697a6564000000000000000081525090612cb95760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601481527f45524331313535423a20496e76616c696420494400000000000000000000000060208201526146508510612d105760405162461bcd60e51b81526004016111a29190613c18565b5060408051808201909152601881527f45524331313535423a20496e76616c696420616d6f756e740000000000000000602082015260018414612d665760405162461bcd60e51b81526004016111a29190613c18565b50614654546040517fcbc3fb560000000000000000000000000000000000000000000000000000000081523060048201523360248201526001600160a01b0388811660448301528781166064830152608482018790529091169063cbc3fb569060a4016020604051808303816000875af1158015612de8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e0c9190614349565b156040518060400160405280601b81526020017f506c61796572486f7573696e673a20546f6b656e206c6f636b6564000000000081525090612e615760405162461bcd60e51b81526004016111a29190613c18565b50835484906001600160a01b0316878114612ebb5760405162461bcd60e51b815260206004820152601e60248201527f45524331313535423a2046726f6d206e6f7420746f6b656e206f776e657200006044820152606481fd5b50859055612eca868685613567565b60408051858152602081018590526001600160a01b03808816929089169133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46001600160a01b0385163b15613033576040517ff23a6e6100000000000000000000000000000000000000000000000000000000808252906001600160a01b0387169063f23a6e6190612f769033908b908a908a908a908a906004016144da565b6020604051808303816000875af1158015612f95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fb9919061443a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146040518060400160405280601a81526020017f45524331313535423a20556e7361666520726563697069656e740000000000008152509061302d5760405162461bcd60e51b81526004016111a29190613c18565b50613090565b60408051808201909152601b81527f45524331313535423a20496e76616c696420726563697069656e74000000000060208201526001600160a01b03861661308e5760405162461bcd60e51b81526004016111a29190613c18565b505b505050505050565b6130a061370f565b6001600160a01b03811661311c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016111a2565b611a4d816138d8565b60008167ffffffffffffffff811115613140576131406144ab565b604051908082528060200260200182016040528015613169578160200160208202803683370190505b50905060008267ffffffffffffffff811115613187576131876144ab565b6040519080825280602002602001820160405280156131b0578160200160208202803683370190505b506146575490915060208381019190830190808915613263576040805160608101909152602980825261ffff8416918c830191611770831115919061471d6020830139906132115760405162461bcd60e51b81526004016111a29190613c18565b50815b81811015613237578d815580875260018087526020978801979096019501613214565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009290921690911790505b881561330f576040805160608101909152602d808252601084901c61ffff16918b830191611770831115919061479e6020830139906132b55760405162461bcd60e51b81526004016111a29190613c18565b50815b818110156132df5761177081018e81558752600180875260209788019790960195016132b8565b5060101b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff929092169190911790505b87156133b55760408051606081019091526030808252602084811c928b84019261177084111592614627908301399061335b5760405162461bcd60e51b81526004016111a29190613c18565b50815b8181101561338557612ee081018e815587526001808752602097880197909601950161335e565b5060201b7fffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff929092169190911790505b6146578190556133c58b886139f6565b8a6001600160a01b031660006001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8989604051613415929190614513565b60405180910390a45050505050505050505050565b60608160000361346d57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115613497578061348181614541565b91506134909050600a836145a8565b9150613471565b60008167ffffffffffffffff8111156134b2576134b26144ab565b6040519080825280601f01601f1916602001820160405280156134dc576020820181803683370190505b5090505b841561355f576134f1600183614457565b91506134fe600a866145bc565b613509906030614299565b60f81b81838151811061351e5761351e6140eb565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350613558600a866145a8565b94506134e0565b949350505050565b60007f0000000000000000000000000000000000000000000000000000000075a6e8a042106135b6577f0000000000000000000000000000000000000000000000000000000075a6e8a06135b8565b425b6001600160a01b03851660009081526146526020526040902054909150601081901c63ffffffff167f0000000000000000000000000000000000000000000000000000000075a6e8a081146136615761ffff8216603083901c82156136345760006136238487614457565b8302656022099fa744029190910190505b6001600160a01b03881660009081526146526020526040902091869003601086901b1760309190911b1790555b50506001600160a01b03831660009081526146526020526040902054601081901c63ffffffff167f0000000000000000000000000000000000000000000000000000000075a6e8a081146130905761ffff8216603083901c82156136dc5760006136cb8487614457565b8302656022099fa744029190910190505b6001600160a01b038716600090815261465260205260409020918601601086901b1760309190911b179055505050505050565b614651546001600160a01b03163314611bee5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016111a2565b614657546040805160608101909152602d808252601083901c61ffff169161177083109161479e6020830139906137b45760405162461bcd60e51b81526004016111a29190613c18565b5061177081018381556001918201601081901b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff85161761465755916137fb9085906139f6565b60408051828152600160208201526001600160a01b0386169160009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a450505050565b6146575460408051606081019091526030808252602083811c92611770841092909161462790830139906138915760405162461bcd60e51b81526004016111a29190613c18565b50612ee081018381556001918201602081901b7fffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffffffff85161761465755916137fb9085906139f6565b61465180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600061ffff801661465754169050611770811060405180606001604052806029815260200161471d602991399061398d5760405162461bcd60e51b81526004016111a29190613c18565b50818155614657805460019081019091556139a99083906139f6565b60408051828152600160208201526001600160a01b0384169160009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a45050565b6001600160a01b0382166000908152614652602052604090205461ffff8116601082901c63ffffffff16603083901c8115613a48576000613a378342614457565b8402656022099fa744029190910190505b6001600160a01b03909516600090815261465260205260409020919093014260101b1760309490941b939093179092555050565b828054613a889061411a565b90600052602060002090601f016020900481019282613aaa5760008555613b0e565b82601f10613ae1578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555613b0e565b82800160010185558215613b0e579182015b82811115613b0e578235825591602001919060010190613af3565b50613b1a929150613b3f565b5090565b604051806208ca000160405280614650906020820280368337509192915050565b5b80821115613b1a5760008155600101613b40565b80356001600160a01b0381168114613b6b57600080fd5b919050565b60008060408385031215613b8357600080fd5b613b8c83613b54565b946020939093013593505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611a4d57600080fd5b600060208284031215613bda57600080fd5b8135613be581613b9a565b9392505050565b60005b83811015613c07578181015183820152602001613bef565b838111156113ad5750506000910152565b6020815260008251806020840152613c37816040850160208701613bec565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600080600060608486031215613c7e57600080fd5b505081359360208301359350604090920135919050565b600060208284031215613ca757600080fd5b5035919050565b600060208284031215613cc057600080fd5b613be582613b54565b60008083601f840112613cdb57600080fd5b50813567ffffffffffffffff811115613cf357600080fd5b6020830191508360208260051b8501011115613d0e57600080fd5b9250929050565b60008083601f840112613d2757600080fd5b50813567ffffffffffffffff811115613d3f57600080fd5b602083019150836020828501011115613d0e57600080fd5b60008060008060008060008060a0898b031215613d7357600080fd5b613d7c89613b54565b9750613d8a60208a01613b54565b9650604089013567ffffffffffffffff80821115613da757600080fd5b613db38c838d01613cc9565b909850965060608b0135915080821115613dcc57600080fd5b613dd88c838d01613cc9565b909650945060808b0135915080821115613df157600080fd5b50613dfe8b828c01613d15565b999c989b5096995094979396929594505050565b60008060008060408587031215613e2857600080fd5b843567ffffffffffffffff80821115613e4057600080fd5b613e4c88838901613cc9565b90965094506020870135915080821115613e6557600080fd5b50613e7287828801613cc9565b95989497509550505050565b600081518084526020808501945080840160005b83811015613eae57815187529582019590820190600101613e92565b509495945050505050565b602081526000613be56020830184613e7e565b60008060208385031215613edf57600080fd5b823567ffffffffffffffff811115613ef657600080fd5b613f0285828601613d15565b90969095509350505050565b8015158114611a4d57600080fd5b60008060408385031215613f2f57600080fd5b613f3883613b54565b91506020830135613f4881613f0e565b809150509250929050565b6000806000806000806000806080898b031215613f6f57600080fd5b883567ffffffffffffffff80821115613f8757600080fd5b613f938c838d01613cc9565b909a50985060208b0135915080821115613fac57600080fd5b613fb88c838d01613cc9565b909850965060408b0135915080821115613fd157600080fd5b613fdd8c838d01613cc9565b909650945060608b0135915080821115613ff657600080fd5b50613dfe8b828c01613cc9565b6208ca008101818360005b6146508110156140375781516001600160a01b031683526020928301929091019060010161400e565b50505092915050565b6000806040838503121561405357600080fd5b61405c83613b54565b915061406a60208401613b54565b90509250929050565b60008060008060008060a0878903121561408c57600080fd5b61409587613b54565b95506140a360208801613b54565b94506040870135935060608701359250608087013567ffffffffffffffff8111156140cd57600080fd5b6140d989828a01613d15565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061412e57607f821691505b602082108103611cfb577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b8054600090600181811c908083168061418157607f831692505b602080841082036141bb577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b8180156141cf57600181146141fe5761422b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0086168952848901965061422b565b60008881526020902060005b868110156142235781548b82015290850190830161420a565b505084890196505b50505050505092915050565b60006142438286614167565b8451614253818360208901613bec565b61425f81830186614167565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156142ac576142ac61426a565b500190565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156142e357600080fd5b8260051b8083602087013760009401602001938452509192915050565b60006001600160a01b0380891683528088166020840152808716604084015280861660608401525060a0608083015261433d60a0830184866142b1565b98975050505050505050565b60006020828403121561435b57600080fd5b8151613be581613f0e565b60408152600061437a6040830186886142b1565b828103602084015261425f8185876142b1565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60006001600160a01b03808b168352808a1660208401525060a0604083015261440360a08301888a6142b1565b82810360608401526144168187896142b1565b9050828103608084015261442b81858761438d565b9b9a5050505050505050505050565b60006020828403121561444c57600080fd5b8151613be581613b9a565b6000828210156144695761446961426a565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156144a6576144a661426a565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006001600160a01b03808916835280881660208401525085604083015284606083015260a0608083015261433d60a08301848661438d565b6040815260006145266040830185613e7e565b82810360208401526145388185613e7e565b95945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145725761457261426a565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826145b7576145b7614579565b500490565b6000826145cb576145cb614579565b50069056fe506c61796572486f7573696e673a204c61637265616e20456d70697265206f766572206d617820616d6f756e7420706572207478506c61796572486f7573696e673a204e6f20636f6e7472616374206d696e74696e67506c61796572486f7573696e673a2052656163686564206d6178204c61637265616e20456d7069726520737570706c79506c61796572486f7573696e673a204172626f726961206f766572206d617820616d6f756e7420706572207478506c61796572486f7573696e673a20546f74616c206f766572206d617820616d6f756e7420706572207478506c61796572486f7573696e673a205075626c69632073616c65206e6f74207265616479506c61796572486f7573696e673a20546f74616c20616d6f756e742062656c6f772032506c61796572486f7573696e673a204e6f7420617070726f76656420666f722072657761726473506c61796572486f7573696e673a2052656163686564206d6178204172626f72696120737570706c79506c61796572486f7573696e673a20496c6c736b616761617264206f766572206d617820616d6f756e7420706572207478506c61796572486f7573696e673a2057686974656c6973742073616c65206e6f74207265616479506c61796572486f7573696e673a2052656163686564206d617820496c6c736b61676161726420737570706c79a2646970667358221220ab14a4c15a796cfa7eaba33e0bae8b63ce81e69700e041524da59d7937d7a8b164736f6c634300080e0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005a5fe90cd115d691ee99d90d3607f7005ea817e50000000000000000000000000000000000000000000000000000000062dae5a00000000000000000000000000000000000000000000000000000000062dd88a00000000000000000000000000000000000000000000000000000000075a6e8a0000000000000000000000000544d219c227856935bf9678e21a2cd012bcc8bd8000000000000000000000000616e6b2ba922968af8d46df9400fc3da17589c5f
-----Decoded View---------------
Arg [0] : owner (address): 0x5a5fe90CD115d691EE99d90D3607f7005Ea817e5
Arg [1] : timestampSaleWhitelist (uint256): 1658512800
Arg [2] : timestampSalePublic (uint256): 1658685600
Arg [3] : timestampRewardsEnd (uint256): 1973872800
Arg [4] : tickets (address): 0x544D219c227856935Bf9678E21A2CD012bCC8bd8
Arg [5] : _lockManager (address): 0x616E6b2Ba922968Af8D46DF9400Fc3DA17589C5f
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000005a5fe90cd115d691ee99d90d3607f7005ea817e5
Arg [1] : 0000000000000000000000000000000000000000000000000000000062dae5a0
Arg [2] : 0000000000000000000000000000000000000000000000000000000062dd88a0
Arg [3] : 0000000000000000000000000000000000000000000000000000000075a6e8a0
Arg [4] : 000000000000000000000000544d219c227856935bf9678e21a2cd012bcc8bd8
Arg [5] : 000000000000000000000000616e6b2ba922968af8d46df9400fc3da17589c5f
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.