Contract Overview
Balance:
0 ETH
ETH Value:
$0.00
My Name Tag:
Not Available
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
Questing
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./QuestingTimeKeeper.sol"; contract Questing is Initializable, QuestingTimeKeeper { using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet; function initialize() external initializer { QuestingTimeKeeper.__QuestingTimeKeeper_init(); } function startQuests( uint256[] calldata _tokenIds, QuestDifficulty[] calldata _difficulties, uint256[] calldata _questLoops) external nonZeroLength(_tokenIds) contractsAreSet whenNotPaused onlyEOA { require(_tokenIds.length == _difficulties.length && _questLoops.length == _difficulties.length, "Bad number of difficulties"); require(treasury.isBridgeWorldPowered(), "Bridge World not powered."); for(uint256 i = 0; i < _tokenIds.length; i++) { LegionMetadata memory _legionMetadata = legionMetadataStore.metadataForLegion(_tokenIds[i]); if(_legionMetadata.legionGeneration == LegionGeneration.RECRUIT) { _startQuestRecruit(_tokenIds[i], _difficulties[i], _questLoops[i], true); } else { _startQuest(_tokenIds[i], _difficulties[i], _questLoops[i], _legionMetadata, true); } } } function _startQuestRecruit( uint256 _tokenId, QuestDifficulty _difficulty, uint256 _numberLoops, bool _transferLegionToContract) private { require(_numberLoops == 1, "Max 1 loop for recruit legion"); require(_difficulty == QuestDifficulty.EASY, "Easy only for recruit"); _startQuestTime(_tokenId); uint256 _requestId = randomizer.requestRandomNumber(); tokenIdToRequestId[_tokenId] = _requestId; tokenIdToQuestDifficulty[_tokenId] = _difficulty; tokenIdToNumberLoops[_tokenId] = _numberLoops; if(_transferLegionToContract) { userToQuestsInProgress[msg.sender].add(_tokenId); // Transfer the legion to be staked in this contract. This will handle // cases when the user doesn't own the tokens legion.adminSafeTransferFrom(msg.sender, address(this), _tokenId); } emit QuestStarted(msg.sender, _tokenId, _requestId, block.timestamp + difficultyToQuestLength[_difficulty], _difficulty); } function _startQuest( uint256 _tokenId, QuestDifficulty _difficulty, uint256 _numberLoops, LegionMetadata memory _legionMetadata, bool _transferLegionToContract) private { uint256 _lpStaked = 0; // 1 loop does not require any staked LP if(_numberLoops != 1) { require(availableAutoQuestLoops.contains(_numberLoops), "Invalid number of loops"); _lpStaked = difficultyToLPNeeded[_difficulty] * _numberLoops; if(_lpStaked > 0) { bool _lpSuccess = lp.transferFrom(msg.sender, address(this), _lpStaked); require(_lpSuccess, "LP transfer failed"); } } uint8 _levelNeededForDifficulty = difficultyToLevelUnlocked[_difficulty]; require(_legionMetadata.questLevel >= _levelNeededForDifficulty, "Difficulty not unlocked."); _startQuestTime(_tokenId); uint256 _requestId = randomizer.requestRandomNumber(); tokenIdToRequestId[_tokenId] = _requestId; tokenIdToQuestDifficulty[_tokenId] = _difficulty; tokenIdToLPStaked[_tokenId] = _lpStaked; tokenIdToNumberLoops[_tokenId] = _numberLoops; if(_transferLegionToContract) { userToQuestsInProgress[msg.sender].add(_tokenId); // Transfer the legion to be staked in this contract. This will handle // cases when the user doesn't own the tokens legion.adminSafeTransferFrom(msg.sender, address(this), _tokenId); } emit QuestStarted(msg.sender, _tokenId, _requestId, block.timestamp + difficultyToQuestLength[_difficulty], _difficulty); } function revealTokensQuests(uint256[] calldata _tokenIds) external contractsAreSet whenNotPaused nonZeroLength(_tokenIds) onlyEOA { for(uint256 i = 0; i < _tokenIds.length; i++) { require(userToQuestsInProgress[msg.sender].contains(_tokenIds[i]), "Not owned by user"); _revealQuest(_tokenIds[i]); } } function _revealQuest(uint256 _tokenId) private { uint256 _requestId = tokenIdToRequestId[_tokenId]; require(_requestId != 0, "Already revealed quests"); require(randomizer.isRandomReady(_requestId), "Random is not ready!"); QuestDifficulty _difficulty = tokenIdToQuestDifficulty[_tokenId]; uint256 _randomNumber = randomizer.revealRandomNumber(_requestId); LegionMetadata memory _legionMetadata = legionMetadataStore.metadataForLegion(_tokenId); for(uint256 i = 0; i < tokenIdToNumberLoops[_tokenId]; i++) { // Ensure each loop has a different random number. _randomNumber = uint256(keccak256(abi.encode(_randomNumber, i))); if(_legionMetadata.legionGeneration == LegionGeneration.RECRUIT) { _calculateAndDistributeRewardRecruit(_tokenId, _randomNumber); } else { _calculateAndDistributeReward(_tokenId, _difficulty, _randomNumber); // Process QP gain/level up. _processQPGainAndLevelUp(_tokenId, _legionMetadata.questLevel); } } delete tokenIdToRequestId[_tokenId]; delete tokenIdToNumberLoops[_tokenId]; } function _calculateAndDistributeRewardRecruit( uint256 _tokenId, uint256 _randomNumber) private { require(starlightId != 0 && shardId != 0 && universalLockId != 0, "Consumable ID not set"); // Recruits are guaranteed starlight. uint8 _starlightAmount = recruitNumberOfStarlight; if(_starlightAmount > 0) { consumable.mint(msg.sender, starlightId, _starlightAmount); } uint8 _shardAmount = 0; if(recruitNumberOfCrystalShards > 0) { uint256 _shardResult = _randomNumber % 100000; _randomNumber = uint256(keccak256(abi.encode(_randomNumber, _randomNumber))); if(_shardResult < recruitCrystalShardsOdds) { _shardAmount = recruitNumberOfCrystalShards; consumable.mint(msg.sender, shardId, _shardAmount); } } uint256 _universalLockResult = _randomNumber % 100000; uint8 _universalLockAmount = 0; if(_universalLockResult < recruitUniversalLockOdds) { consumable.mint(msg.sender, universalLockId, 1); _universalLockAmount = 1; } emit QuestRevealed( msg.sender, _tokenId, QuestReward( _starlightAmount, _shardAmount, _universalLockAmount, 0 ) ); } function _calculateAndDistributeReward( uint256 _tokenId, QuestDifficulty _difficulty, uint256 _randomNumber) private { require(starlightId != 0 && shardId != 0 && universalLockId != 0, "Consumable ID not set"); // Every user is guaranteed 2 rewards per quest. uint8 _starlightAmount = difficultyToStarlightAmount[_difficulty]; uint8 _shardAmount = difficultyToShardAmount[_difficulty]; if(_starlightAmount > 0) { consumable.mint(msg.sender, starlightId, _starlightAmount); } if(_shardAmount > 0) { consumable.mint(msg.sender, shardId, _shardAmount); } uint256 _rewardedTreasureId = 0; uint256 _treasureResult = _randomNumber % 100000; if(_treasureResult < treasureDropOdds) { _randomNumber = uint256(keccak256(abi.encode(_randomNumber, _randomNumber))); uint256 _treasureTierResult = _randomNumber % 100000; uint256[5] memory _tierOdds = difficultyToTierOdds[_difficulty]; uint256 _topRange = 0; for(uint256 i = 0; i < _tierOdds.length; i++) { _topRange += _tierOdds[i]; if(_treasureTierResult < _topRange) { _randomNumber = uint256(keccak256(abi.encode(_randomNumber, _randomNumber))); // Tiers are 1 index based. _rewardedTreasureId = treasureMetadataStore.getRandomTreasureForTier(uint8(i + 1), _randomNumber); treasure.mint(msg.sender, _rewardedTreasureId, 1); break; } } } _randomNumber = uint256(keccak256(abi.encode(_randomNumber, _randomNumber))); uint256 _universalLockResult = _randomNumber % 100000; uint8 _universalLockAmount = 0; if(_universalLockResult < universalLockDropOdds) { consumable.mint(msg.sender, universalLockId, 1); _universalLockAmount = 1; } emit QuestRevealed( msg.sender, _tokenId, QuestReward( _starlightAmount, _shardAmount, _universalLockAmount, _rewardedTreasureId ) ); } function _processQPGainAndLevelUp(uint256 _tokenId, uint8 _currentQuestLevel) private { // No need to do anything if they're at the max level. if(_currentQuestLevel >= maxQuestLevel) { return; } // Add QP relative to their current level. tokenIdToQP[_tokenId] += levelToQPGainedPerQuest[_currentQuestLevel]; // While the user is not max level // and they have enough to go to the next level. while(_currentQuestLevel < maxQuestLevel && tokenIdToQP[_tokenId] >= levelToQPNeeded[_currentQuestLevel]) { tokenIdToQP[_tokenId] -= levelToQPNeeded[_currentQuestLevel]; legionMetadataStore.increaseQuestLevel(_tokenId); _currentQuestLevel++; } } function finishTokenQuests(uint256[] calldata _tokenIds) external contractsAreSet whenNotPaused nonZeroLength(_tokenIds) onlyEOA { for(uint256 i = 0; i < _tokenIds.length; i++) { require(userToQuestsInProgress[msg.sender].contains(_tokenIds[i]), "Not owned by user"); _finishQuest(_tokenIds[i], true); } } function restartTokenQuests( uint256[] calldata _tokenIds, QuestDifficulty[] calldata _difficulties, uint256[] calldata _questLoops) external contractsAreSet whenNotPaused nonZeroLength(_tokenIds) onlyEOA { require(_tokenIds.length == _difficulties.length && _questLoops.length == _difficulties.length, "Bad number of difficulties"); require(treasury.isBridgeWorldPowered(), "Bridge World not powered."); for(uint256 i = 0; i < _tokenIds.length; i++) { require(userToQuestsInProgress[msg.sender].contains(_tokenIds[i]), "Not owned by user"); _finishQuest(_tokenIds[i], false); LegionMetadata memory _legionMetadata = legionMetadataStore.metadataForLegion(_tokenIds[i]); if(_legionMetadata.legionGeneration == LegionGeneration.RECRUIT) { _startQuestRecruit(_tokenIds[i], _difficulties[i], _questLoops[i], false); } else { _startQuest(_tokenIds[i], _difficulties[i], _questLoops[i], _legionMetadata, false); } } } function _finishQuest(uint256 _tokenId, bool _sendLegionBackAndClearData) private { uint256 _requestId = tokenIdToRequestId[_tokenId]; require(_requestId == 0, "Reward not revealed yet"); require(_isQuestCooldownDone(_tokenId), "Quest cooldown has not completed"); uint256 _lpStakedAmount = tokenIdToLPStaked[_tokenId]; // Save on gas by not writing unnecessarily to the chain. These will be overwritten when questing is started again if(_sendLegionBackAndClearData) { delete tokenIdToQuestDifficulty[_tokenId]; delete tokenIdToQuestStartTime[_tokenId]; delete tokenIdToLPStaked[_tokenId]; userToQuestsInProgress[msg.sender].remove(_tokenId); legion.adminSafeTransferFrom(address(this), msg.sender, _tokenId); } if(_lpStakedAmount > 0) { bool _lpSucceed = lp.transferFrom(address(this), msg.sender, _lpStakedAmount); require(_lpSucceed, "LP transfer failed"); } emit QuestFinished(msg.sender, _tokenId); } function isQuestReadyToReveal(uint256 _tokenId) external view returns(bool) { uint256 _requestId = tokenIdToRequestId[_tokenId]; require(_requestId > 0, "Not active or already revealed"); return randomizer.isRandomReady(_requestId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./QuestingSettings.sol"; abstract contract QuestingTimeKeeper is Initializable, QuestingSettings { function __QuestingTimeKeeper_init() internal initializer { QuestingSettings.__QuestingSettings_init(); } function _startQuestTime(uint256 _tokenId) internal { tokenIdToQuestStartTime[_tokenId] = block.timestamp; } function _isQuestCooldownDone(uint256 _tokenId) internal view returns(bool) { uint256 _startTime = tokenIdToQuestStartTime[_tokenId]; QuestDifficulty _questDifficulty = tokenIdToQuestDifficulty[_tokenId]; uint256 _cooldown = difficultyToQuestLength[_questDifficulty]; return block.timestamp >= _startTime + _cooldown; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./QuestingContracts.sol"; abstract contract QuestingSettings is Initializable, QuestingContracts { using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet; function __QuestingSettings_init() internal initializer { QuestingContracts.__QuestingContracts_init(); } function setQuestLengths( uint256 _easyLength, uint256 _mediumLength, uint256 _hardLength) external onlyAdminOrOwner { difficultyToQuestLength[QuestDifficulty.EASY] = _easyLength; difficultyToQuestLength[QuestDifficulty.MEDIUM] = _mediumLength; difficultyToQuestLength[QuestDifficulty.HARD] = _hardLength; } function setLevelDifficultyUnlocks( uint8 _easyLevel, uint8 _mediumLevel, uint8 _hardLevel) external onlyAdminOrOwner { difficultyToLevelUnlocked[QuestDifficulty.EASY] = _easyLevel; difficultyToLevelUnlocked[QuestDifficulty.MEDIUM] = _mediumLevel; difficultyToLevelUnlocked[QuestDifficulty.HARD] = _hardLevel; } function setLevelSteps( uint8 _maxQuestLevel, uint256[] calldata _qpNeededForEachLevel, uint256[] calldata _qpGainedAtEachLevel ) external onlyAdminOrOwner { require(_maxQuestLevel > 0, "Bad max level"); require(_qpNeededForEachLevel.length == _maxQuestLevel - 1, "Not enough QP steps"); require(_qpGainedAtEachLevel.length == _maxQuestLevel - 1, "Not enough QP gained steps"); maxQuestLevel = _maxQuestLevel; delete levelToQPNeeded; delete levelToQPGainedPerQuest; levelToQPNeeded.push(0); levelToQPGainedPerQuest.push(0); for(uint256 i = 0; i < _maxQuestLevel - 1; i++) { levelToQPNeeded.push(_qpNeededForEachLevel[i]); levelToQPGainedPerQuest.push(_qpGainedAtEachLevel[i]); } } // Should be provided in order Easy, Medium, and Hard. function setGuaranteedDropAmounts( uint8[3] calldata _shardAmounts, uint8[3] calldata _starlightAmounts) external onlyAdminOrOwner { difficultyToStarlightAmount[QuestDifficulty.EASY] = _shardAmounts[0]; difficultyToStarlightAmount[QuestDifficulty.MEDIUM] = _shardAmounts[1]; difficultyToStarlightAmount[QuestDifficulty.HARD] = _shardAmounts[2]; difficultyToShardAmount[QuestDifficulty.EASY] = _starlightAmounts[0]; difficultyToShardAmount[QuestDifficulty.MEDIUM] = _starlightAmounts[1]; difficultyToShardAmount[QuestDifficulty.HARD] = _starlightAmounts[2]; } function setTreasureSettings( uint256 _treasureDropOdds, uint256 _universalLockDropOdds, uint256 _starlightId, uint256 _shardId, uint256 _universalLockId) external onlyAdminOrOwner { treasureDropOdds = _treasureDropOdds; starlightId = _starlightId; shardId = _shardId; universalLockDropOdds = _universalLockDropOdds; universalLockId = _universalLockId; } function setLPNeeded(uint256[3] calldata _lpNeeded) external onlyAdminOrOwner { difficultyToLPNeeded[QuestDifficulty.EASY] = _lpNeeded[0]; difficultyToLPNeeded[QuestDifficulty.MEDIUM] = _lpNeeded[1]; difficultyToLPNeeded[QuestDifficulty.HARD] = _lpNeeded[2]; } function setAutoQuestLoops(uint256[] calldata _availableLoops) external onlyAdminOrOwner { uint256[] memory _oldValues = availableAutoQuestLoops.values(); for(uint256 i = 0; i < _oldValues.length; i++) { availableAutoQuestLoops.remove(_oldValues[i]); } for(uint256 i = 0; i < _availableLoops.length; i++) { availableAutoQuestLoops.add(_availableLoops[i]); } } function setRecruitSettings( uint8 _recruitNumberOfStarlight, uint8 _recruitNumberOfCrystalShards, uint256 _recruitCrystalShardsOdds, uint256 _recruitUniversalLockOdds) external onlyAdminOrOwner { recruitNumberOfStarlight = _recruitNumberOfStarlight; recruitNumberOfCrystalShards = _recruitNumberOfCrystalShards; recruitCrystalShardsOdds = _recruitCrystalShardsOdds; recruitUniversalLockOdds = _recruitUniversalLockOdds; } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./QuestingState.sol"; abstract contract QuestingContracts is Initializable, QuestingState { function __QuestingContracts_init() internal initializer { QuestingState.__QuestingState_init(); } function setContracts( address _randomizerAddress, address _treasureAddress, address _legionAddress, address _treasureMetadataStoreAddress, address _legionMetadataStoreAddress, address _lpAddress, address _consumableAddress, address _treasuryAddress) external onlyAdminOrOwner { randomizer = IRandomizer(_randomizerAddress); treasure = ITreasure(_treasureAddress); legion = ILegion(_legionAddress); treasureMetadataStore = ITreasureMetadataStore(_treasureMetadataStoreAddress); legionMetadataStore = ILegionMetadataStore(_legionMetadataStoreAddress); lp = ILP(_lpAddress); consumable = IConsumable(_consumableAddress); treasury = ITreasury(_treasuryAddress); } modifier contractsAreSet() { require(address(randomizer) != address(0) && address(treasure) != address(0) && address(legion) != address(0) && address(treasureMetadataStore) != address(0) && address(legionMetadataStore) != address(0) && address(consumable) != address(0) && address(treasury) != address(0) && address(lp) != address(0), "Contracts aren't set"); _; } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC721/utils/ERC721HolderUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC1155/utils/ERC1155HolderUpgradeable.sol"; import "../../shared/randomizer/IRandomizer.sol"; import "./IQuesting.sol"; import "../../shared/AdminableUpgradeable.sol"; import "../external/ITreasure.sol"; import "../external/ILP.sol"; import "../legion/ILegion.sol"; import "../consumable/IConsumable.sol"; import "../treasuremetadatastore/ITreasureMetadataStore.sol"; import "../legionmetadatastore/ILegionMetadataStore.sol"; import "../treasury/ITreasury.sol"; abstract contract QuestingState is Initializable, IQuesting, ERC721HolderUpgradeable, ERC1155HolderUpgradeable, AdminableUpgradeable { using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet; event QuestStarted(address indexed _owner, uint256 indexed _tokenId, uint256 indexed _requestId, uint256 _finishTime, QuestDifficulty _difficulty); event QuestRevealed(address indexed _owner, uint256 indexed _tokenId, QuestReward _reward); event QuestFinished(address indexed _owner, uint256 indexed _tokenId); IRandomizer public randomizer; ITreasure public treasure; ILegion public legion; IConsumable public consumable; ITreasureMetadataStore public treasureMetadataStore; ILegionMetadataStore public legionMetadataStore; ILP public lp; mapping(QuestDifficulty => uint256) public difficultyToQuestLength; mapping(QuestDifficulty => uint8) public difficultyToLevelUnlocked; mapping(QuestDifficulty => uint8) public difficultyToStarlightAmount; mapping(QuestDifficulty => uint8) public difficultyToShardAmount; // Ordered from tier 1 (index 0) -> tier 5 (index 4) mapping(QuestDifficulty => uint256[5]) public difficultyToTierOdds; mapping(QuestDifficulty => uint256) public difficultyToLPNeeded; uint8 public maxQuestLevel; uint256[] public levelToQPNeeded; uint256[] public levelToQPGainedPerQuest; mapping(address => EnumerableSetUpgradeable.UintSet) internal userToQuestsInProgress; mapping(uint256 => uint256) public tokenIdToQP; mapping(uint256 => uint256) public tokenIdToQuestStartTime; mapping(uint256 => uint256) public tokenIdToRequestId; mapping(uint256 => QuestDifficulty) public tokenIdToQuestDifficulty; mapping(uint256 => uint256) public tokenIdToLPStaked; mapping(uint256 => uint256) public tokenIdToNumberLoops; uint256 public treasureDropOdds; uint256 public universalLockDropOdds; uint256 public starlightId; uint256 public shardId; uint256 public universalLockId; EnumerableSetUpgradeable.UintSet internal availableAutoQuestLoops; uint8 public recruitNumberOfStarlight; uint8 public recruitNumberOfCrystalShards; // Out of 100,000 uint256 public recruitCrystalShardsOdds; uint256 public recruitUniversalLockOdds; ITreasury public treasury; function __QuestingState_init() internal initializer { AdminableUpgradeable.__Adminable_init(); ERC721HolderUpgradeable.__ERC721Holder_init(); ERC1155HolderUpgradeable.__ERC1155Holder_init(); difficultyToQuestLength[QuestDifficulty.EASY] = 8 hours; difficultyToQuestLength[QuestDifficulty.MEDIUM] = 12 hours; difficultyToQuestLength[QuestDifficulty.HARD] = 16 hours; difficultyToLevelUnlocked[QuestDifficulty.EASY] = 1; difficultyToLevelUnlocked[QuestDifficulty.MEDIUM] = 3; difficultyToLevelUnlocked[QuestDifficulty.HARD] = 5; maxQuestLevel = 6; // Level starts at 1 levelToQPNeeded.push(0); levelToQPNeeded.push(100); levelToQPNeeded.push(200); levelToQPNeeded.push(500); levelToQPNeeded.push(1000); levelToQPNeeded.push(2000); // Level starts at 1 levelToQPGainedPerQuest.push(0); levelToQPGainedPerQuest.push(10); levelToQPGainedPerQuest.push(10); levelToQPGainedPerQuest.push(20); levelToQPGainedPerQuest.push(20); levelToQPGainedPerQuest.push(40); treasureDropOdds = 20000; universalLockDropOdds = 10; difficultyToTierOdds[QuestDifficulty.EASY] = [0, 2500, 5000, 15000, 77500]; difficultyToTierOdds[QuestDifficulty.MEDIUM] = [1500, 5000, 7000, 17000, 69500]; difficultyToTierOdds[QuestDifficulty.HARD] = [2500, 9000, 8000, 22000, 58500]; availableAutoQuestLoops.add(3); availableAutoQuestLoops.add(9); availableAutoQuestLoops.add(15); difficultyToLPNeeded[QuestDifficulty.EASY] = 5 ether; difficultyToLPNeeded[QuestDifficulty.MEDIUM] = 10 ether; difficultyToLPNeeded[QuestDifficulty.HARD] = 15 ether; difficultyToStarlightAmount[QuestDifficulty.EASY] = 3; difficultyToStarlightAmount[QuestDifficulty.MEDIUM] = 4; difficultyToStarlightAmount[QuestDifficulty.HARD] = 5; difficultyToShardAmount[QuestDifficulty.EASY] = 3; difficultyToShardAmount[QuestDifficulty.MEDIUM] = 4; difficultyToShardAmount[QuestDifficulty.HARD] = 5; recruitNumberOfStarlight = 1; recruitNumberOfCrystalShards = 1; recruitCrystalShardsOdds = 50000; recruitUniversalLockOdds = 1; } } enum QuestDifficulty { EASY, MEDIUM, HARD } // This is okay to modify, as it used in an event rather than in state. struct QuestReward { uint8 starlightAmount; uint8 crystalShardAmount; uint8 universalLockAmount; // The ID of the treasure received. Will be 0 if no treasure received. uint256 treasureId; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol) pragma solidity ^0.8.0; import "../IERC721ReceiverUpgradeable.sol"; import "../../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}. */ contract ERC721HolderUpgradeable is Initializable, IERC721ReceiverUpgradeable { function __ERC721Holder_init() internal onlyInitializing { __ERC721Holder_init_unchained(); } function __ERC721Holder_init_unchained() internal onlyInitializing { } /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address, address, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC721Received.selector; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Holder.sol) pragma solidity ^0.8.0; import "./ERC1155ReceiverUpgradeable.sol"; import "../../../proxy/utils/Initializable.sol"; /** * @dev _Available since v3.1._ */ contract ERC1155HolderUpgradeable is Initializable, ERC1155ReceiverUpgradeable { function __ERC1155Holder_init() internal onlyInitializing { __ERC165_init_unchained(); __ERC1155Receiver_init_unchained(); __ERC1155Holder_init_unchained(); } function __ERC1155Holder_init_unchained() internal onlyInitializing { } function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IRandomizer { // Sets the number of blocks that must pass between increment the commitId and seeding the random // Admin function setNumBlocksAfterIncrement(uint8 _numBlocksAfterIncrement) external; // Increments the commit id. // Admin function incrementCommitId() external; // Adding the random number needs to be done AFTER incrementing the commit id on a separate transaction. If // these are done together, there is a potential vulnerability to front load a commit when the bad actor // sees the value of the random number. function addRandomForCommit(uint256 _seed) external; // Returns a request ID for a random number. This is unique. function requestRandomNumber() external returns(uint256); // Returns the random number for the given request ID. Will revert // if the random is not ready. function revealRandomNumber(uint256 _requestId) external view returns(uint256); // Returns if the random number for the given request ID is ready or not. Call // before calling revealRandomNumber. function isRandomReady(uint256 _requestId) external view returns(bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IQuesting { }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./UtilitiesUpgradeable.sol"; // Do not add state to this contract. // contract AdminableUpgradeable is UtilitiesUpgradeable { mapping(address => bool) private admins; function __Adminable_init() internal initializer { UtilitiesUpgradeable.__Utilities__init(); } function addAdmin(address _address) external onlyOwner { admins[_address] = true; } function addAdmins(address[] calldata _addresses) external onlyOwner { for(uint256 i = 0; i < _addresses.length; i++) { admins[_addresses[i]] = true; } } function removeAdmin(address _address) external onlyOwner { admins[_address] = false; } function removeAdmins(address[] calldata _addresses) external onlyOwner { for(uint256 i = 0; i < _addresses.length; i++) { admins[_addresses[i]] = false; } } function setPause(bool _shouldPause) external onlyAdminOrOwner { if(_shouldPause) { _pause(); } else { _unpause(); } } function isAdmin(address _address) public view returns(bool) { return admins[_address]; } modifier onlyAdmin() { require(admins[msg.sender], "Not admin"); _; } modifier onlyAdminOrOwner() { require(admins[msg.sender] || isOwner(), "Not admin or owner"); _; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ITreasure { // Transfers the treasure at the given ID of the given amount. // Requires that the legions are pre-approved. // function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes memory data) external; // Transfers the treasure at the given ID of the given amount. // function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory data) external; // Admin only. // function mint(address _account, uint256 _tokenId, uint256 _amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ILP { // Transfers the given amount to the recipient's wallet. Returns a boolean indicating if it was // successful or not. function transferFrom(address _sender, address _recipient, uint256 _amount) external returns(bool); // Transfer the given amount to the recipient's wallet. The sender is the caller of this function. // Returns a boolean indicating if it was successful or not. function transfer(address _recipient, uint256 _amount) external returns(bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol"; interface ILegion is IERC721MetadataUpgradeable { // Mints a legion to the given address. Returns the token ID. // Admin only. function safeMint(address _to) external returns(uint256); // Sets the URI for the given token id. Token must exist. // Admin only. function setTokenURI(uint256 _tokenId, string calldata _tokenURI) external; // Transfers the token to the given address. Does not need approval. _from still must be the owner of the token. // Admin only. function adminSafeTransferFrom(address _from, address _to, uint256 _tokenId) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; interface IConsumable is IERC1155Upgradeable { function mint(address _to, uint256 _id, uint256 _amount) external; function burn(address account, uint256 id, uint256 value) external; function burnBatch(address account, uint256[] memory ids, uint256[] memory values) external; function adminSafeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount) external; function adminSafeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./TreasureMetadataStoreState.sol"; interface ITreasureMetadataStore { // Sets the metadata for the given Ids. // Admin only. function setMetadataForIds(uint256[] calldata _ids, TreasureMetadata[] calldata _metadatas) external; // Returns if the given ID has metadata set. function hasMetadataForTreasureId(uint256 _treasureId) external view returns(bool); // Returns the metadata for the given ID. Reverts if no metadata for the ID is set. function getMetadataForTreasureId(uint256 _treasureId) external view returns(TreasureMetadata memory); // For the given tier, gets a random MINTABLE treasure id. function getRandomTreasureForTier(uint8 _tier, uint256 _randomNumber) external view returns(uint256); } // Do not change. Stored in state. struct TreasureMetadata { TreasureCategory category; uint8 tier; // Out of 100,000 uint32 craftingBreakOdds; bool isMintable; uint256 consumableIdDropWhenBreak; } enum TreasureCategory { ALCHEMY, ARCANA, BREWING, ENCHANTER, LEATHERWORKING, SMITHING }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./LegionMetadataStoreState.sol"; interface ILegionMetadataStore { // Sets the intial metadata for a token id. // Admin only. function setInitialMetadataForLegion(address _owner, uint256 _tokenId, LegionGeneration _generation, LegionClass _class, LegionRarity _rarity, uint256 _oldId) external; // Increases the quest level by one. It is up to the calling contract to regulate the max quest level. No validation. // Admin only. function increaseQuestLevel(uint256 _tokenId) external; // Increases the craft level by one. It is up to the calling contract to regulate the max craft level. No validation. // Admin only. function increaseCraftLevel(uint256 _tokenId) external; // Increases the rank of the given constellation to the given number. It is up to the calling contract to regulate the max constellation rank. No validation. // Admin only. function increaseConstellationRank(uint256 _tokenId, Constellation _constellation, uint8 _to) external; // Returns the metadata for the given legion. function metadataForLegion(uint256 _tokenId) external view returns(LegionMetadata memory); // Returns the tokenUri for the given token. function tokenURI(uint256 _tokenId) external view returns(string memory); } // As this will likely change in the future, this should not be used to store state, but rather // as parameters and return values from functions. struct LegionMetadata { LegionGeneration legionGeneration; LegionClass legionClass; LegionRarity legionRarity; uint8 questLevel; uint8 craftLevel; uint8[6] constellationRanks; uint256 oldId; } enum Constellation { FIRE, EARTH, WIND, WATER, LIGHT, DARK } enum LegionRarity { LEGENDARY, RARE, SPECIAL, UNCOMMON, COMMON, RECRUIT } enum LegionClass { RECRUIT, SIEGE, FIGHTER, ASSASSIN, RANGED, SPELLCASTER, RIVERMAN, NUMERAIRE, ALL_CLASS, ORIGIN } enum LegionGeneration { GENESIS, AUXILIARY, RECRUIT }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ITreasury { function isBridgeWorldPowered() external view returns(bool); function forwardCoinsToMine(uint256 _totalMagicSent) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721ReceiverUpgradeable { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol) pragma solidity ^0.8.0; import "../IERC1155ReceiverUpgradeable.sol"; import "../../../utils/introspection/ERC165Upgradeable.sol"; import "../../../proxy/utils/Initializable.sol"; /** * @dev _Available since v3.1._ */ abstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable { function __ERC1155Receiver_init() internal onlyInitializing { __ERC165_init_unchained(); __ERC1155Receiver_init_unchained(); } function __ERC1155Receiver_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC1155ReceiverUpgradeable).interfaceId || super.supportsInterface(interfaceId); } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155ReceiverUpgradeable is IERC165Upgradeable { /** @dev Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. To accept the transfer, this must return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` (i.e. 0xf23a6e61, or its own function selector). @param operator The address which initiated the transfer (i.e. msg.sender) @param from The address which previously owned the token @param id The ID of the token being transferred @param value The amount of tokens being transferred @param data Additional data with no specified format @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** @dev Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. To accept the transfer(s), this must return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` (i.e. 0xbc197c81, or its own function selector). @param operator The address which initiated the batch transfer (i.e. msg.sender) @param from The address which previously owned the token @param ids An array containing ids of each token being transferred (order and length must match values array) @param values An array containing amounts of each token being transferred (order and length must match ids array) @param data Additional data with no specified format @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { __ERC165_init_unchained(); } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; contract UtilitiesUpgradeable is Initializable, OwnableUpgradeable, PausableUpgradeable { function __Utilities__init() internal initializer { OwnableUpgradeable.__Ownable_init(); PausableUpgradeable.__Pausable_init(); _pause(); } modifier nonZeroAddress(address _address) { require(address(0) != _address, "0 address"); _; } modifier nonZeroLength(uint[] memory _array) { require(_array.length > 0, "Empty array"); _; } modifier lengthsAreEqual(uint[] memory _array1, uint[] memory _array2) { require(_array1.length == _array2.length, "Unequal lengths"); _; } modifier onlyEOA() { /* solhint-disable avoid-tx-origin */ require(msg.sender == tx.origin, "No contracts"); _; } function isOwner() internal view returns(bool) { return owner() == msg.sender; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.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 OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Context_init_unchained(); __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @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 ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { __Context_init_unchained(); } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../IERC721Upgradeable.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721MetadataUpgradeable is IERC721Upgradeable { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../../shared/AdminableUpgradeable.sol"; import "./ITreasureMetadataStore.sol"; import "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol"; abstract contract TreasureMetadataStoreState is AdminableUpgradeable { mapping(uint8 => EnumerableSetUpgradeable.UintSet) internal tierToMintableTreasureIds; mapping(uint256 => TreasureMetadata) internal treasureIdToMetadata; function __TreasureMetadataStoreState_init() internal initializer { AdminableUpgradeable.__Adminable_init(); } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "../../shared/AdminableUpgradeable.sol"; import "./ILegionMetadataStore.sol"; abstract contract LegionMetadataStoreState is Initializable, AdminableUpgradeable { event LegionQuestLevelUp(uint256 indexed _tokenId, uint8 _questLevel); event LegionCraftLevelUp(uint256 indexed _tokenId, uint8 _craftLevel); event LegionConstellationRankUp(uint256 indexed _tokenId, Constellation indexed _constellation, uint8 _rank); event LegionCreated(address indexed _owner, uint256 indexed _tokenId, LegionGeneration _generation, LegionClass _class, LegionRarity _rarity); mapping(uint256 => LegionGeneration) internal idToGeneration; mapping(uint256 => LegionClass) internal idToClass; mapping(uint256 => LegionRarity) internal idToRarity; mapping(uint256 => uint256) internal idToOldId; mapping(uint256 => uint8) internal idToQuestLevel; mapping(uint256 => uint8) internal idToCraftLevel; mapping(uint256 => uint8[6]) internal idToConstellationRanks; mapping(LegionGeneration => mapping(LegionClass => mapping(LegionRarity => mapping(uint256 => string)))) internal _genToClassToRarityToOldIdToUri; function __LegionMetadataStoreState_init() internal initializer { AdminableUpgradeable.__Adminable_init(); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
[{"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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"QuestFinished","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"components":[{"internalType":"uint8","name":"starlightAmount","type":"uint8"},{"internalType":"uint8","name":"crystalShardAmount","type":"uint8"},{"internalType":"uint8","name":"universalLockAmount","type":"uint8"},{"internalType":"uint256","name":"treasureId","type":"uint256"}],"indexed":false,"internalType":"struct QuestReward","name":"_reward","type":"tuple"}],"name":"QuestRevealed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_requestId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_finishTime","type":"uint256"},{"indexed":false,"internalType":"enum QuestDifficulty","name":"_difficulty","type":"uint8"}],"name":"QuestStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"addAdmins","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"consumable","outputs":[{"internalType":"contract IConsumable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum QuestDifficulty","name":"","type":"uint8"}],"name":"difficultyToLPNeeded","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum QuestDifficulty","name":"","type":"uint8"}],"name":"difficultyToLevelUnlocked","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum QuestDifficulty","name":"","type":"uint8"}],"name":"difficultyToQuestLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum QuestDifficulty","name":"","type":"uint8"}],"name":"difficultyToShardAmount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum QuestDifficulty","name":"","type":"uint8"}],"name":"difficultyToStarlightAmount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum QuestDifficulty","name":"","type":"uint8"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"difficultyToTierOdds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"finishTokenQuests","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"isQuestReadyToReveal","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"legion","outputs":[{"internalType":"contract ILegion","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"legionMetadataStore","outputs":[{"internalType":"contract ILegionMetadataStore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"levelToQPGainedPerQuest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"levelToQPNeeded","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lp","outputs":[{"internalType":"contract ILP","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxQuestLevel","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"randomizer","outputs":[{"internalType":"contract IRandomizer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"recruitCrystalShardsOdds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"recruitNumberOfCrystalShards","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"recruitNumberOfStarlight","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"recruitUniversalLockOdds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"removeAdmins","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"enum QuestDifficulty[]","name":"_difficulties","type":"uint8[]"},{"internalType":"uint256[]","name":"_questLoops","type":"uint256[]"}],"name":"restartTokenQuests","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"revealTokensQuests","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_availableLoops","type":"uint256[]"}],"name":"setAutoQuestLoops","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_randomizerAddress","type":"address"},{"internalType":"address","name":"_treasureAddress","type":"address"},{"internalType":"address","name":"_legionAddress","type":"address"},{"internalType":"address","name":"_treasureMetadataStoreAddress","type":"address"},{"internalType":"address","name":"_legionMetadataStoreAddress","type":"address"},{"internalType":"address","name":"_lpAddress","type":"address"},{"internalType":"address","name":"_consumableAddress","type":"address"},{"internalType":"address","name":"_treasuryAddress","type":"address"}],"name":"setContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8[3]","name":"_shardAmounts","type":"uint8[3]"},{"internalType":"uint8[3]","name":"_starlightAmounts","type":"uint8[3]"}],"name":"setGuaranteedDropAmounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[3]","name":"_lpNeeded","type":"uint256[3]"}],"name":"setLPNeeded","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_easyLevel","type":"uint8"},{"internalType":"uint8","name":"_mediumLevel","type":"uint8"},{"internalType":"uint8","name":"_hardLevel","type":"uint8"}],"name":"setLevelDifficultyUnlocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_maxQuestLevel","type":"uint8"},{"internalType":"uint256[]","name":"_qpNeededForEachLevel","type":"uint256[]"},{"internalType":"uint256[]","name":"_qpGainedAtEachLevel","type":"uint256[]"}],"name":"setLevelSteps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_shouldPause","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_easyLength","type":"uint256"},{"internalType":"uint256","name":"_mediumLength","type":"uint256"},{"internalType":"uint256","name":"_hardLength","type":"uint256"}],"name":"setQuestLengths","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_recruitNumberOfStarlight","type":"uint8"},{"internalType":"uint8","name":"_recruitNumberOfCrystalShards","type":"uint8"},{"internalType":"uint256","name":"_recruitCrystalShardsOdds","type":"uint256"},{"internalType":"uint256","name":"_recruitUniversalLockOdds","type":"uint256"}],"name":"setRecruitSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_treasureDropOdds","type":"uint256"},{"internalType":"uint256","name":"_universalLockDropOdds","type":"uint256"},{"internalType":"uint256","name":"_starlightId","type":"uint256"},{"internalType":"uint256","name":"_shardId","type":"uint256"},{"internalType":"uint256","name":"_universalLockId","type":"uint256"}],"name":"setTreasureSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shardId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"starlightId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"enum QuestDifficulty[]","name":"_difficulties","type":"uint8[]"},{"internalType":"uint256[]","name":"_questLoops","type":"uint256[]"}],"name":"startQuests","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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdToLPStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdToNumberLoops","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdToQP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdToQuestDifficulty","outputs":[{"internalType":"enum QuestDifficulty","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdToQuestStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdToRequestId","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":[],"name":"treasure","outputs":[{"internalType":"contract ITreasure","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasureDropOdds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasureMetadataStore","outputs":[{"internalType":"contract ITreasureMetadataStore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"contract ITreasury","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"universalLockDropOdds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"universalLockId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506153df806100206000396000f3fe608060405234801561001057600080fd5b50600436106103af5760003560e01c80638a7bf804116101f4578063cb3a4a741161011a578063f0c1ebe4116100ad578063f2fde38b1161007c578063f2fde38b146108e7578063f68fa578146108fa578063f93309d11461090d578063fb00011e1461092057600080fd5b8063f0c1ebe414610862578063f10fb58414610893578063f161217e146108a7578063f23a6e61146108c857600080fd5b8063dd26bd84116100e9578063dd26bd8414610804578063e50d19df14610828578063e520fc7e1461083b578063e820cb6c1461084f57600080fd5b8063cb3a4a74146107c0578063d214c14b146107d3578063d67896a9146107dd578063d7dfe4dd146107f057600080fd5b8063a46879e711610192578063ba12528911610161578063ba12528914610771578063bc197c8114610784578063bd31ba33146107a3578063bedb86fb146107ad57600080fd5b8063a46879e714610712578063ac99ccb614610733578063ad72e1a514610746578063aea889761461076757600080fd5b80639ad8d6f7116101ce5780639ad8d6f7146106c55780639b9c9a66146106d85780639c54df64146106eb578063a0122ec6146106fe57600080fd5b80638a7bf8041461067c5780638da5cb5b1461069057806390a47013146106a157600080fd5b8063377e11e0116102d95780636696f79c1161027757806371a54c851161024657806371a54c851461062f5780638129fc1c1461064257806383d022401461064a57806385b34d971461066e57600080fd5b80636696f79c146105ed578063675857eb146106005780637048027514610614578063715018a61461062757600080fd5b80634ed8d2c0116102b35780634ed8d2c0146105a257806356b048ea146105c35780635c975abb146105cd57806361d027b3146105d957600080fd5b8063377e11e0146105645780634106f1b91461057757806349af34671461059857600080fd5b806324537d37116103515780632d3a5323116103205780632d3a5323146105085780632d5240231461051b5780632fc87b921461052e578063313c06a01461053857600080fd5b806324537d371461048657806324d7806c146104a75780632521ff47146104d457806327f6eb8e146104e757600080fd5b80630cad8b161161038d5780630cad8b1614610419578063150b7a021461042e5780631785f53c146104655780631c686ee81461047857600080fd5b806301ffc9a7146103b457806303070e45146103dc57806306b8ae04146103f4575b600080fd5b6103c76103c2366004614737565b610933565b60405190151581526020015b60405180910390f35b6103e66101a95481565b6040519081526020016103d3565b6101b05461040790610100900460ff1681565b60405160ff90911681526020016103d3565b61042c6104273660046147ad565b61096a565b005b61044c61043c366004614943565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016103d3565b61042c6104733660046149ab565b610e34565b6101b0546104079060ff1681565b6103e66104943660046149c6565b6101a86020526000908152604090205481565b6103c76104b53660046149ab565b6001600160a01b0316600090815261015f602052604090205460ff1690565b61042c6104e23660046149df565b610e80565b6103e66104f53660046149c6565b6101a76020526000908152604090205481565b61042c610516366004614a0b565b610f34565b6103e6610529366004614a53565b610f8e565b6103e66101b25481565b6101985461054c906001600160a01b031681565b6040516001600160a01b0390911681526020016103d3565b61042c610572366004614a7f565b610fb4565b6103e66105853660046149c6565b6101a46020526000908152604090205481565b6103e66101b15481565b6103e66105b0366004614ac1565b61019e6020526000908152604090205481565b6103e66101ad5481565b61012d5460ff166103c7565b6101b35461054c906001600160a01b031681565b61042c6105fb366004614a7f565b611056565b6101945461054c906001600160a01b031681565b61042c6106223660046149ab565b611142565b61042c611191565b61042c61063d366004614aed565b6111c7565b61042c611233565b610407610658366004614ac1565b61019b6020526000908152604090205460ff1681565b61019f546104079060ff1681565b6101975461054c906001600160a01b031681565b60fb546001600160a01b031661054c565b6104076106af366004614ac1565b61019c6020526000908152604090205460ff1681565b61042c6106d3366004614b33565b6112ad565b61042c6106e6366004614bdb565b611381565b61042c6106f9366004614a7f565b61143d565b6101965461054c906001600160a01b031681565b6103e66107203660046149c6565b6101a36020526000908152604090205481565b61042c610741366004614a7f565b6114da565b6103e66107543660046149c6565b6101a56020526000908152604090205481565b6103e66101ab5481565b6103e661077f3660046149c6565b6116ad565b61044c610792366004614c77565b63bc197c8160e01b95945050505050565b6103e66101ac5481565b61042c6107bb366004614d2f565b6116cf565b61042c6107ce366004614d4c565b611723565b6103e66101aa5481565b61042c6107eb366004614d81565b611939565b6101955461054c906001600160a01b031681565b610407610812366004614ac1565b61019a6020526000908152604090205460ff1681565b6103e66108363660046149c6565b611b99565b6101935461054c906001600160a01b031681565b61042c61085d366004614e04565b611baa565b6108866108703660046149c6565b6101a66020526000908152604090205460ff1681565b6040516103d39190614e87565b6101925461054c906001600160a01b031681565b6103e66108b5366004614ac1565b6101996020526000908152604090205481565b61044c6108d6366004614e95565b63f23a6e6160e01b95945050505050565b61042c6108f53660046149ab565b611c82565b61042c6109083660046147ad565b611d1a565b61042c61091b366004614a7f565b61214b565b6103c761092e3660046149c6565b612320565b60006001600160e01b03198216630271189760e51b148061096457506301ffc9a760e01b6001600160e01b03198316145b92915050565b610192546001600160a01b0316158015906109905750610193546001600160a01b031615155b80156109a75750610194546001600160a01b031615155b80156109be5750610196546001600160a01b031615155b80156109d55750610197546001600160a01b031615155b80156109ec5750610195546001600160a01b031615155b8015610a0357506101b3546001600160a01b031615155b8015610a1a5750610198546001600160a01b031615155b610a3f5760405162461bcd60e51b8152600401610a3690614efa565b60405180910390fd5b61012d5460ff1615610a635760405162461bcd60e51b8152600401610a3690614f28565b85858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050825115159150610ab890505760405162461bcd60e51b8152600401610a3690614f52565b333214610ad75760405162461bcd60e51b8152600401610a3690614f77565b8584148015610ae557508184145b610b315760405162461bcd60e51b815260206004820152601a60248201527f426164206e756d626572206f6620646966666963756c746965730000000000006044820152606401610a36565b6101b360009054906101000a90046001600160a01b03166001600160a01b031663ca1709556040518163ffffffff1660e01b815260040160206040518083038186803b158015610b8057600080fd5b505afa158015610b94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb89190614f9d565b610c005760405162461bcd60e51b8152602060048201526019602482015278213934b233b2902bb7b93632103737ba103837bbb2b932b21760391b6044820152606401610a36565b60005b86811015610e2a57610c52888883818110610c2057610c20614fba565b3360009081526101a2602090815260409091209391020135905060009081526001919091016020526040902054151590565b610c6e5760405162461bcd60e51b8152600401610a3690614fd0565b610c91888883818110610c8357610c83614fba565b905060200201356000612401565b610197546000906001600160a01b031663f15fbdf28a8a85818110610cb857610cb8614fba565b905060200201356040518263ffffffff1660e01b8152600401610cdd91815260200190565b6101806040518083038186803b158015610cf657600080fd5b505afa158015610d0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d2e919061508c565b9050600281516002811115610d4557610d45614e4f565b1415610db357610dae898984818110610d6057610d60614fba565b90506020020135888885818110610d7957610d79614fba565b9050602002016020810190610d8e9190614ac1565b878786818110610da057610da0614fba565b90506020020135600061267f565b610e17565b610e17898984818110610dc857610dc8614fba565b90506020020135888885818110610de157610de1614fba565b9050602002016020810190610df69190614ac1565b878786818110610e0857610e08614fba565b90506020020135846000612915565b5080610e2281615139565b915050610c03565b5050505050505050565b60fb546001600160a01b03163314610e5e5760405162461bcd60e51b8152600401610a3690615154565b6001600160a01b0316600090815261015f60205260409020805460ff19169055565b33600090815261015f602052604090205460ff1680610ea25750610ea2612d28565b610ebe5760405162461bcd60e51b8152600401610a3690615189565b6101996020527f64ff465cfcabcf42f95776227c293cec69d4462f43d19ab892c0f096d0681446929092557f25b1716dafbf144c17ee7e01561ffe7a3113c6c5ff9fba1fb9b7a7d39e4c38f75560026000527f4074d44e33158386ca63db52321f67f5d8423dbdefd3bf591730a62f6576595c55565b33600090815261015f602052604090205460ff1680610f565750610f56612d28565b610f725760405162461bcd60e51b8152600401610a3690615189565b6101a9949094556101ab919091556101ac556101aa556101ad55565b61019d6020528160005260406000208160058110610fab57600080fd5b01549150829050565b60fb546001600160a01b03163314610fde5760405162461bcd60e51b8152600401610a3690615154565b60005b8181101561105157600061015f600085858581811061100257611002614fba565b905060200201602081019061101791906149ab565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558061104981615139565b915050610fe1565b505050565b33600090815261015f602052604090205460ff16806110785750611078612d28565b6110945760405162461bcd60e51b8152600401610a3690615189565b60006110a16101ae612d4c565b905060005b81518110156110f0576110dd8282815181106110c4576110c4614fba565b60200260200101516101ae612d5990919063ffffffff16565b50806110e881615139565b9150506110a6565b5060005b8281101561113c5761112984848381811061111157611111614fba565b905060200201356101ae612d6590919063ffffffff16565b508061113481615139565b9150506110f4565b50505050565b60fb546001600160a01b0316331461116c5760405162461bcd60e51b8152600401610a3690615154565b6001600160a01b0316600090815261015f60205260409020805460ff19166001179055565b60fb546001600160a01b031633146111bb5760405162461bcd60e51b8152600401610a3690615154565b6111c56000612d71565b565b33600090815261015f602052604090205460ff16806111e957506111e9612d28565b6112055760405162461bcd60e51b8152600401610a3690615189565b6101b0805460ff9485166101000261ffff199091169490951693909317939093179091556101b1556101b255565b600054610100900460ff1661124e5760005460ff1615611252565b303b155b61126e5760405162461bcd60e51b8152600401610a36906151b5565b600054610100900460ff16158015611290576000805461ffff19166101011790555b611298612dc3565b80156112aa576000805461ff00191690555b50565b33600090815261015f602052604090205460ff16806112cf57506112cf612d28565b6112eb5760405162461bcd60e51b8152600401610a3690615189565b61019280546001600160a01b03199081166001600160a01b039a8b161790915561019380548216988a169890981790975561019480548816968916969096179095556101968054871694881694909417909355610197805486169287169290921790915561019880548516918616919091179055610195805484169185169190911790556101b380549092169216919091179055565b33600090815261015f602052604090205460ff16806113a357506113a3612d28565b6113bf5760405162461bcd60e51b8152600401610a3690615189565b61019e602090815281357f5b1e587894c781c322714baac11bfa7b0da2aeb4590a6dcb5f31ea08c486311b558101357f2d695d1bdc89be0990c9b1cefd0e589f7fbb3368bfb8d91126956a95dcf16073556002600052604001357f1482f8fde77c2e0a1223b839dd85e5e0d40575a23bb6b13896f241a0b36fe0d855565b60fb546001600160a01b031633146114675760405162461bcd60e51b8152600401610a3690615154565b60005b8181101561105157600161015f600085858581811061148b5761148b614fba565b90506020020160208101906114a091906149ab565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055806114d281615139565b91505061146a565b610192546001600160a01b0316158015906115005750610193546001600160a01b031615155b80156115175750610194546001600160a01b031615155b801561152e5750610196546001600160a01b031615155b80156115455750610197546001600160a01b031615155b801561155c5750610195546001600160a01b031615155b801561157357506101b3546001600160a01b031615155b801561158a5750610198546001600160a01b031615155b6115a65760405162461bcd60e51b8152600401610a3690614efa565b61012d5460ff16156115ca5760405162461bcd60e51b8152600401610a3690614f28565b8181808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505082511515915061161f90505760405162461bcd60e51b8152600401610a3690614f52565b33321461163e5760405162461bcd60e51b8152600401610a3690614f77565b60005b8281101561113c5761165e848483818110610c2057610c20614fba565b61167a5760405162461bcd60e51b8152600401610a3690614fd0565b61169b84848381811061168f5761168f614fba565b90506020020135612e28565b806116a581615139565b915050611641565b6101a081815481106116be57600080fd5b600091825260209091200154905081565b33600090815261015f602052604090205460ff16806116f157506116f1612d28565b61170d5760405162461bcd60e51b8152600401610a3690615189565b801561171b576112aa61311f565b6112aa613196565b33600090815261015f602052604090205460ff16806117455750611745612d28565b6117615760405162461bcd60e51b8152600401610a3690615189565b61176e6020830183615203565b6000805261019b60209081527f50a97c7b30cb1a28824c00fb61d93f0784e76a1d9a50667766f7b8f4ed03a657805460ff191660ff93909316929092179091556117be9060408401908401615203565b600160005261019b6020527f1871dda0514920f847a38e1c1a849cdd4f94e8f7f85b81658671fe5ca8ad11ef805460ff191660ff9290921691909117905561180c6060830160408401615203565b600260005261019b60209081527f2a1d4f6078f8c36c9403e0edc3d4b2935b0182bca5295cb74bc8b6bfebfa2a5d805460ff191660ff939093169290921790915561185990820182615203565b6000805261019c60209081527f4b419d2fef537193bcacf7d8e3aa1e02cb76a5e91c9927ac0b4328ae4cf88823805460ff191660ff93909316929092179091556118a99060408301908301615203565b600160005261019c6020527fc72eaf8cd3b5c9a905003f86a3aad459ca788a7847e8657dc6013b9edcb24e94805460ff191660ff929092169190911790556118f76060820160408301615203565b600260005261019c6020527f6ac6d6b719103e0be90d8f1dc8f262c2aa4b9ba5e23a506ed6f056d83b5bbc70805460ff191660ff929092169190911790555050565b33600090815261015f602052604090205460ff168061195b575061195b612d28565b6119775760405162461bcd60e51b8152600401610a3690615189565b60008560ff16116119ba5760405162461bcd60e51b815260206004820152600d60248201526c109859081b585e081b195d995b609a1b6044820152606401610a36565b6119c5600186615220565b60ff168314611a0c5760405162461bcd60e51b81526020600482015260136024820152724e6f7420656e6f75676820515020737465707360681b6044820152606401610a36565b611a17600186615220565b60ff168114611a685760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f756768205150206761696e65642073746570730000000000006044820152606401610a36565b61019f805460ff191660ff8716179055611a856101a0600061468b565b611a926101a1600061468b565b6101a08054600181810190925560007f7980fe0f714a613298681d64b7b8ffa7b148338dd52429f307d72798d5c317c49091018190556101a18054928301815581527f138323e2a914e847043e23cddd114fae8437deb6d72c040f1025356455849bda9091018190555b611b07600187615220565b60ff16811015611b91576101a0858583818110611b2657611b26614fba565b835460018101855560009485526020948590209190940292909201359190920155506101a1838383818110611b5d57611b5d614fba565b8354600181018555600094855260209485902091909402929092013591909201555080611b8981615139565b915050611afc565b505050505050565b6101a181815481106116be57600080fd5b33600090815261015f602052604090205460ff1680611bcc5750611bcc612d28565b611be85760405162461bcd60e51b8152600401610a3690615189565b61019a6020527fdf87daca02df9cb008fcda558ae984ab92a5826e62dcff2b5180361f9f18ebf2805460ff1990811660ff958616179091557f082445bb554fade7877a24b2437efaaa3cb9ee97beb4fd4e4c6f863073eb85c4805482169385169390931790925560026000527fef497134997ac3f497d45996287bb42d7b7318af1499095a908382aa5a592ebd8054919093169116179055565b60fb546001600160a01b03163314611cac5760405162461bcd60e51b8152600401610a3690615154565b6001600160a01b038116611d115760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a36565b6112aa81612d71565b85858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050825115159150611d6f90505760405162461bcd60e51b8152600401610a3690614f52565b610192546001600160a01b031615801590611d955750610193546001600160a01b031615155b8015611dac5750610194546001600160a01b031615155b8015611dc35750610196546001600160a01b031615155b8015611dda5750610197546001600160a01b031615155b8015611df15750610195546001600160a01b031615155b8015611e0857506101b3546001600160a01b031615155b8015611e1f5750610198546001600160a01b031615155b611e3b5760405162461bcd60e51b8152600401610a3690614efa565b61012d5460ff1615611e5f5760405162461bcd60e51b8152600401610a3690614f28565b333214611e7e5760405162461bcd60e51b8152600401610a3690614f77565b8584148015611e8c57508184145b611ed85760405162461bcd60e51b815260206004820152601a60248201527f426164206e756d626572206f6620646966666963756c746965730000000000006044820152606401610a36565b6101b360009054906101000a90046001600160a01b03166001600160a01b031663ca1709556040518163ffffffff1660e01b815260040160206040518083038186803b158015611f2757600080fd5b505afa158015611f3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5f9190614f9d565b611fa75760405162461bcd60e51b8152602060048201526019602482015278213934b233b2902bb7b93632103737ba103837bbb2b932b21760391b6044820152606401610a36565b60005b86811015610e2a57610197546000906001600160a01b031663f15fbdf28a8a85818110611fd957611fd9614fba565b905060200201356040518263ffffffff1660e01b8152600401611ffe91815260200190565b6101806040518083038186803b15801561201757600080fd5b505afa15801561202b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061204f919061508c565b905060028151600281111561206657612066614e4f565b14156120d4576120cf89898481811061208157612081614fba565b9050602002013588888581811061209a5761209a614fba565b90506020020160208101906120af9190614ac1565b8787868181106120c1576120c1614fba565b90506020020135600161267f565b612138565b6121388989848181106120e9576120e9614fba565b9050602002013588888581811061210257612102614fba565b90506020020160208101906121179190614ac1565b87878681811061212957612129614fba565b90506020020135846001612915565b508061214381615139565b915050611faa565b610192546001600160a01b0316158015906121715750610193546001600160a01b031615155b80156121885750610194546001600160a01b031615155b801561219f5750610196546001600160a01b031615155b80156121b65750610197546001600160a01b031615155b80156121cd5750610195546001600160a01b031615155b80156121e457506101b3546001600160a01b031615155b80156121fb5750610198546001600160a01b031615155b6122175760405162461bcd60e51b8152600401610a3690614efa565b61012d5460ff161561223b5760405162461bcd60e51b8152600401610a3690614f28565b8181808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505082511515915061229090505760405162461bcd60e51b8152600401610a3690614f52565b3332146122af5760405162461bcd60e51b8152600401610a3690614f77565b60005b8281101561113c576122cf848483818110610c2057610c20614fba565b6122eb5760405162461bcd60e51b8152600401610a3690614fd0565b61230e84848381811061230057612300614fba565b905060200201356001612401565b8061231881615139565b9150506122b2565b60008181526101a560205260408120548061237d5760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420616374697665206f7220616c72656164792072657665616c656400006044820152606401610a36565b6101925460405163f030210760e01b8152600481018390526001600160a01b039091169063f03021079060240160206040518083038186803b1580156123c257600080fd5b505afa1580156123d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123fa9190614f9d565b9392505050565b60008281526101a56020526040902054801561245f5760405162461bcd60e51b815260206004820152601760248201527f526577617264206e6f742072657665616c6564207965740000000000000000006044820152606401610a36565b61246883613212565b6124b45760405162461bcd60e51b815260206004820181905260248201527f517565737420636f6f6c646f776e20686173206e6f7420636f6d706c657465646044820152606401610a36565b60008381526101a7602052604090205482156125785760008481526101a660209081526040808320805460ff191690556101a482528083208390556101a782528083208390553383526101a2909152902061250f9085612d59565b50610194546040516383291f8760e01b81526001600160a01b03909116906383291f879061254590309033908990600401615243565b600060405180830381600087803b15801561255f57600080fd5b505af1158015612573573d6000803e3d6000fd5b505050505b801561264c57610198546040516323b872dd60e01b81526000916001600160a01b0316906323b872dd906125b490309033908790600401615243565b602060405180830381600087803b1580156125ce57600080fd5b505af11580156125e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126069190614f9d565b90508061264a5760405162461bcd60e51b81526020600482015260126024820152711314081d1c985b9cd9995c8819985a5b195960721b6044820152606401610a36565b505b604051849033907f8ac429d7fc602a05164517560aadca9c5327863f7f5077d92f78a2e91922722e90600090a350505050565b816001146126cf5760405162461bcd60e51b815260206004820152601d60248201527f4d61782031206c6f6f7020666f722072656372756974206c6567696f6e0000006044820152606401610a36565b60008360028111156126e3576126e3614e4f565b146127285760405162461bcd60e51b815260206004820152601560248201527411585cde481bdb9b1e48199bdc881c9958dc9d5a5d605a1b6044820152606401610a36565b60008481526101a46020908152604080832042905561019254815163433c53d960e11b815291516001600160a01b0390911692638678a7b2926004808201939182900301818787803b15801561277d57600080fd5b505af1158015612791573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127b59190615267565b60008681526101a5602090815260408083208490556101a690915290208054919250859160ff191660018360028111156127f1576127f1614e4f565b021790555060008581526101a8602052604090208390558115612891573360009081526101a2602052604090206128289086612d65565b50610194546040516383291f8760e01b81526001600160a01b03909116906383291f879061285e90339030908a90600401615243565b600060405180830381600087803b15801561287857600080fd5b505af115801561288c573d6000803e3d6000fd5b505050505b8085337ff9bf523eabbad837ea3c0c583eda3c19f5d05a9a1c3254e37480198a72e05f4461019960008960028111156128cc576128cc614e4f565b60028111156128dd576128dd614e4f565b815260200190815260200160002054426128f79190615280565b88604051612906929190615298565b60405180910390a45050505050565b600083600114612a935760008481526101af602052604090205461297b5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206e756d626572206f66206c6f6f70730000000000000000006044820152606401610a36565b8361019e600087600281111561299357612993614e4f565b60028111156129a4576129a4614e4f565b8152602001908152602001600020546129bd91906152ac565b90508015612a9357610198546040516323b872dd60e01b81526000916001600160a01b0316906323b872dd906129fb90339030908790600401615243565b602060405180830381600087803b158015612a1557600080fd5b505af1158015612a29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a4d9190614f9d565b905080612a915760405162461bcd60e51b81526020600482015260126024820152711314081d1c985b9cd9995c8819985a5b195960721b6044820152606401610a36565b505b600061019a6000876002811115612aac57612aac614e4f565b6002811115612abd57612abd614e4f565b8152602081019190915260400160002054606085015160ff918216925016811115612b2a5760405162461bcd60e51b815260206004820152601860248201527f446966666963756c7479206e6f7420756e6c6f636b65642e00000000000000006044820152606401610a36565b60008781526101a46020908152604080832042905561019254815163433c53d960e11b815291516001600160a01b0390911692638678a7b2926004808201939182900301818787803b158015612b7f57600080fd5b505af1158015612b93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bb79190615267565b60008981526101a5602090815260408083208490556101a690915290208054919250889160ff19166001836002811115612bf357612bf3614e4f565b021790555060008881526101a7602090815260408083208690556101a890915290208690558315612ca1573360009081526101a260205260409020612c389089612d65565b50610194546040516383291f8760e01b81526001600160a01b03909116906383291f8790612c6e90339030908d90600401615243565b600060405180830381600087803b158015612c8857600080fd5b505af1158015612c9c573d6000803e3d6000fd5b505050505b8088337ff9bf523eabbad837ea3c0c583eda3c19f5d05a9a1c3254e37480198a72e05f4461019960008c6002811115612cdc57612cdc614e4f565b6002811115612ced57612ced614e4f565b81526020019081526020016000205442612d079190615280565b8b604051612d16929190615298565b60405180910390a45050505050505050565b600033612d3d60fb546001600160a01b031690565b6001600160a01b031614905090565b606060006123fa83613282565b60006123fa83836132de565b60006123fa83836133d1565b60fb80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16612dde5760005460ff1615612de2565b303b155b612dfe5760405162461bcd60e51b8152600401610a36906151b5565b600054610100900460ff16158015612e20576000805461ffff19166101011790555b611298613420565b60008181526101a5602052604090205480612e855760405162461bcd60e51b815260206004820152601760248201527f416c72656164792072657665616c6564207175657374730000000000000000006044820152606401610a36565b6101925460405163f030210760e01b8152600481018390526001600160a01b039091169063f03021079060240160206040518083038186803b158015612eca57600080fd5b505afa158015612ede573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f029190614f9d565b612f455760405162461bcd60e51b815260206004820152601460248201527352616e646f6d206973206e6f742072656164792160601b6044820152606401610a36565b60008281526101a6602052604080822054610192549151634ad30a7560e01b81526004810185905260ff90911692916001600160a01b031690634ad30a759060240160206040518083038186803b158015612f9f57600080fd5b505afa158015612fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd79190615267565b610197546040516378afdef960e11b8152600481018790529192506000916001600160a01b039091169063f15fbdf2906024016101806040518083038186803b15801561302357600080fd5b505afa158015613037573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061305b919061508c565b905060005b60008681526101a860205260409020548110156130fa57604080516020810185905290810182905260600160408051601f19818403018152919052805160209091012092506002825160028111156130ba576130ba614e4f565b14156130cf576130ca8684613485565b6130e8565b6130da86858561376e565b6130e8868360600151613cd1565b806130f281615139565b915050613060565b505050600092835250506101a5602090815260408083208390556101a8909152812055565b61012d5460ff16156131435760405162461bcd60e51b8152600401610a3690614f28565b61012d805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586131793390565b6040516001600160a01b03909116815260200160405180910390a1565b61012d5460ff166131e05760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610a36565b61012d805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33613179565b60008181526101a460209081526040808320546101a690925282205460ff16826101998183600281111561324857613248614e4f565b600281111561325957613259614e4f565b815260200190815260200160002054905080836132769190615280565b42101595945050505050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156132d257602002820191906000526020600020905b8154815260200190600101908083116132be575b50505050509050919050565b600081815260018301602052604081205480156133c75760006133026001836152cb565b8554909150600090613316906001906152cb565b905081811461337b57600086600001828154811061333657613336614fba565b906000526020600020015490508087600001848154811061335957613359614fba565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061338c5761338c6152e2565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610964565b6000915050610964565b600081815260018301602052604081205461341857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610964565b506000610964565b600054610100900460ff1661343b5760005460ff161561343f565b303b155b61345b5760405162461bcd60e51b8152600401610a36906151b5565b600054610100900460ff1615801561347d576000805461ffff19166101011790555b611298613e44565b6101ab541580159061349957506101ac5415155b80156134a757506101ad5415155b6134eb5760405162461bcd60e51b815260206004820152601560248201527410dbdb9cdd5b58589b19481251081b9bdd081cd95d605a1b6044820152606401610a36565b6101b05460ff16801561356357610195546101ab54604051630ab714fb60e11b81526001600160a01b039092169163156e29f6916135309133919086906004016152f8565b600060405180830381600087803b15801561354a57600080fd5b505af115801561355e573d6000803e3d6000fd5b505050505b6101b054600090610100900460ff161561363f576000613586620186a08561531c565b60408051602081018790529081018690529091506060016040516020818303038152906040528051906020012060001c93506101b15481101561363d576101b054610195546101ac54604051630ab714fb60e11b815261010090930460ff1694506001600160a01b039091169163156e29f69161360a9133919087906004016152f8565b600060405180830381600087803b15801561362457600080fd5b505af1158015613638573d6000803e3d6000fd5b505050505b505b600061364e620186a08561531c565b905060006101b2548210156136d357610195546101ad54604051630ab714fb60e11b81523360048201526024810191909152600160448201526001600160a01b039091169063156e29f690606401600060405180830381600087803b1580156136b657600080fd5b505af11580156136ca573d6000803e3d6000fd5b50505050600190505b6040805160808101825260ff80871682528581166020830152831681830152600060608201529051879133917fc255245a3e4dbbee8d3a2bf2e49e4fe763a2ceace1a69b09f80803770cc20ffc9161375e91600060808201905060ff835116825260ff602084015116602083015260ff60408401511660408301526060830151606083015292915050565b60405180910390a3505050505050565b6101ab541580159061378257506101ac5415155b801561379057506101ad5415155b6137d45760405162461bcd60e51b815260206004820152601560248201527410dbdb9cdd5b58589b19481251081b9bdd081cd95d605a1b6044820152606401610a36565b600061019b60008460028111156137ed576137ed614e4f565b60028111156137fe576137fe614e4f565b8152602081019190915260400160009081205460ff16915061019c8185600281111561382c5761382c614e4f565b600281111561383d5761383d614e4f565b815260208101919091526040016000205460ff90811691508216156138c757610195546101ab54604051630ab714fb60e11b81526001600160a01b039092169163156e29f6916138949133919087906004016152f8565b600060405180830381600087803b1580156138ae57600080fd5b505af11580156138c2573d6000803e3d6000fd5b505050505b60ff81161561393b57610195546101ac54604051630ab714fb60e11b81526001600160a01b039092169163156e29f6916139089133919086906004016152f8565b600060405180830381600087803b15801561392257600080fd5b505af1158015613936573d6000803e3d6000fd5b505050505b60008061394b620186a08661531c565b90506101a954811015613b8357604080516020810187905290810186905260600160408051601f19818403018152919052805160209091012094506000613995620186a08761531c565b9050600061019d60008960028111156139b0576139b0614e4f565b60028111156139c1576139c1614e4f565b815260208101919091526040908101600020815160a08101928390529160059082845b8154815260200190600101908083116139e457505050505090506000805b6005811015613b7e57828160058110613a1d57613a1d614fba565b6020020151613a2c9083615280565b915081841015613b6c5760408051602081018b90529081018a905260600160408051601f198184030181529190528051602090910120610196549099506001600160a01b0316637498e03f613a82836001615280565b6040516001600160e01b031960e084901b16815260ff9091166004820152602481018c905260440160206040518083038186803b158015613ac257600080fd5b505afa158015613ad6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613afa9190615267565b61019354604051630ab714fb60e11b815233600482015260248101839052600160448201529197506001600160a01b03169063156e29f690606401600060405180830381600087803b158015613b4f57600080fd5b505af1158015613b63573d6000803e3d6000fd5b50505050613b7e565b80613b7681615139565b915050613a02565b505050505b604080516020810187905290810186905260600160408051601f19818403018152919052805160209091012094506000613bc0620186a08761531c565b905060006101aa54821015613c4557610195546101ad54604051630ab714fb60e11b81523360048201526024810191909152600160448201526001600160a01b039091169063156e29f690606401600060405180830381600087803b158015613c2857600080fd5b505af1158015613c3c573d6000803e3d6000fd5b50505050600190505b604080516080808201835260ff808a16808452898216602080860191825287841686880190815260609687018c815288519485529251851691840191909152519092169481019490945251918301919091528a9133917fc255245a3e4dbbee8d3a2bf2e49e4fe763a2ceace1a69b09f80803770cc20ffc910160405180910390a3505050505050505050565b61019f5460ff90811690821610613ce6575050565b6101a18160ff1681548110613cfd57613cfd614fba565b90600052602060002001546101a360008481526020019081526020016000206000828254613d2b9190615280565b90915550505b61019f5460ff908116908216108015613d7f57506101a08160ff1681548110613d5c57613d5c614fba565b90600052602060002001546101a360008481526020019081526020016000205410155b15613e40576101a08160ff1681548110613d9b57613d9b614fba565b90600052602060002001546101a360008481526020019081526020016000206000828254613dc991906152cb565b90915550506101975460405163ccd5efbf60e01b8152600481018490526001600160a01b039091169063ccd5efbf90602401600060405180830381600087803b158015613e1557600080fd5b505af1158015613e29573d6000803e3d6000fd5b505050508080613e389061533e565b915050613d31565b5050565b600054610100900460ff16613e5f5760005460ff1615613e63565b303b155b613e7f5760405162461bcd60e51b8152600401610a36906151b5565b600054610100900460ff16158015613ea1576000805461ffff19166101011790555b611298600054610100900460ff16613ebf5760005460ff1615613ec3565b303b155b613edf5760405162461bcd60e51b8152600401610a36906151b5565b600054610100900460ff16158015613f01576000805461ffff19166101011790555b613f09614452565b613f116144b7565b613f196144e6565b6170807f64ff465cfcabcf42f95776227c293cec69d4462f43d19ab892c0f096d06814465561a8c07f25b1716dafbf144c17ee7e01561ffe7a3113c6c5ff9fba1fb9b7a7d39e4c38f75561e1007f4074d44e33158386ca63db52321f67f5d8423dbdefd3bf591730a62f6576595c557fdf87daca02df9cb008fcda558ae984ab92a5826e62dcff2b5180361f9f18ebf28054600160ff1991821681179092557f082445bb554fade7877a24b2437efaaa3cb9ee97beb4fd4e4c6f863073eb85c48054821660031790557fef497134997ac3f497d45996287bb42d7b7318af1499095a908382aa5a592ebd80546005908316811790915561019f80549092166006179091556101a08054808401825560007f7980fe0f714a613298681d64b7b8ffa7b148338dd52429f307d72798d5c317c4918201819055825480860184556064908301558254808601845560c890830155825480860184556101f490830155825480860184556103e89083015582548086019093556107d092909101919091556101a1805480850182557f138323e2a914e847043e23cddd114fae8437deb6d72c040f1025356455849bda90810183905581548086018355600a9082018190558254808701845582018190558254808701845560149083018190558354808801855583015582549586019092556028940193909355614e206101a9556101aa929092556040805160a0810182528381526109c460208083019190915261138892820192909252613a98606082015262012ebc608082015292805261019d9052614183917f13dcb3c6205eccc5df5a4a7821d488c75d9d361908855b59d022fe13c7bb4f1d916146a9565b506040805160a0810182526105dc8152611388602080830191909152611b5892820192909252614268606082015262010f7c6080820152600160005261019d9091526141f2907f228719b3ab53201bbb41968c40b0b5cdf287f8c98ba3ec9532f722219a6d86ff9060056146a9565b506040805160a0810182526109c48152612328602080830191909152611f40928201929092526155f0606082015261e4846080820152600260005261019d909152614260907f29ea485743245ef5c5c24b1a283e9aaa2745fd5e9f6154d72f7ef154d10421bc9060056146ee565b5061426e6101ae6003612d65565b5061427c6101ae6009612d65565b5061428a6101ae600f612d65565b50674563918244f400007f5b1e587894c781c322714baac11bfa7b0da2aeb4590a6dcb5f31ea08c486311b55678ac7230489e800007f2d695d1bdc89be0990c9b1cefd0e589f7fbb3368bfb8d91126956a95dcf160735567d02ab486cedc00007f1482f8fde77c2e0a1223b839dd85e5e0d40575a23bb6b13896f241a0b36fe0d8557f50a97c7b30cb1a28824c00fb61d93f0784e76a1d9a50667766f7b8f4ed03a6578054600360ff1991821681179092557f1871dda0514920f847a38e1c1a849cdd4f94e8f7f85b81658671fe5ca8ad11ef8054821660049081179091557f2a1d4f6078f8c36c9403e0edc3d4b2935b0182bca5295cb74bc8b6bfebfa2a5d80546005908416811790915561019c6020527f4b419d2fef537193bcacf7d8e3aa1e02cb76a5e91c9927ac0b4328ae4cf88823805484169094179093557fc72eaf8cd3b5c9a905003f86a3aad459ca788a7847e8657dc6013b9edcb24e9480548316909117905560026000527f6ac6d6b719103e0be90d8f1dc8f262c2aa4b9ba5e23a506ed6f056d83b5bbc70805490911690911790556101b0805461ffff191661010117905561c3506101b15560016101b25580156112aa576000805461ff001916905550565b600054610100900460ff1661446d5760005460ff1615614471565b303b155b61448d5760405162461bcd60e51b8152600401610a36906151b5565b600054610100900460ff161580156144af576000805461ffff19166101011790555b61129861451d565b600054610100900460ff166144de5760405162461bcd60e51b8152600401610a369061535e565b6111c5614592565b600054610100900460ff1661450d5760405162461bcd60e51b8152600401610a369061535e565b614515614592565b6144de614592565b600054610100900460ff166145385760005460ff161561453c565b303b155b6145585760405162461bcd60e51b8152600401610a36906151b5565b600054610100900460ff1615801561457a576000805461ffff19166101011790555b6145826145b9565b61458a6145f0565b61129861311f565b600054610100900460ff166111c55760405162461bcd60e51b8152600401610a369061535e565b600054610100900460ff166145e05760405162461bcd60e51b8152600401610a369061535e565b6145e8614592565b6111c5614627565b600054610100900460ff166146175760405162461bcd60e51b8152600401610a369061535e565b61461f614592565b6111c5614657565b600054610100900460ff1661464e5760405162461bcd60e51b8152600401610a369061535e565b6111c533612d71565b600054610100900460ff1661467e5760405162461bcd60e51b8152600401610a369061535e565b61012d805460ff19169055565b50805460008255906000526020600020908101906112aa9190614722565b82600581019282156146de579160200282015b828111156146de578251829062ffffff169055916020019190600101906146bc565b506146ea929150614722565b5090565b82600581019282156146de579160200282015b828111156146de578251829061ffff16905591602001919060010190614701565b5b808211156146ea5760008155600101614723565b60006020828403121561474957600080fd5b81356001600160e01b0319811681146123fa57600080fd5b60008083601f84011261477357600080fd5b50813567ffffffffffffffff81111561478b57600080fd5b6020830191508360208260051b85010111156147a657600080fd5b9250929050565b600080600080600080606087890312156147c657600080fd5b863567ffffffffffffffff808211156147de57600080fd5b6147ea8a838b01614761565b9098509650602089013591508082111561480357600080fd5b61480f8a838b01614761565b9096509450604089013591508082111561482857600080fd5b5061483589828a01614761565b979a9699509497509295939492505050565b80356001600160a01b038116811461485e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff8111828210171561489c5761489c614863565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156148cb576148cb614863565b604052919050565b600082601f8301126148e457600080fd5b813567ffffffffffffffff8111156148fe576148fe614863565b614911601f8201601f19166020016148a2565b81815284602083860101111561492657600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561495957600080fd5b61496285614847565b935061497060208601614847565b925060408501359150606085013567ffffffffffffffff81111561499357600080fd5b61499f878288016148d3565b91505092959194509250565b6000602082840312156149bd57600080fd5b6123fa82614847565b6000602082840312156149d857600080fd5b5035919050565b6000806000606084860312156149f457600080fd5b505081359360208301359350604090920135919050565b600080600080600060a08688031215614a2357600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600381106112aa57600080fd5b60008060408385031215614a6657600080fd5b8235614a7181614a46565b946020939093013593505050565b60008060208385031215614a9257600080fd5b823567ffffffffffffffff811115614aa957600080fd5b614ab585828601614761565b90969095509350505050565b600060208284031215614ad357600080fd5b81356123fa81614a46565b60ff811681146112aa57600080fd5b60008060008060808587031215614b0357600080fd5b8435614b0e81614ade565b93506020850135614b1e81614ade565b93969395505050506040820135916060013590565b600080600080600080600080610100898b031215614b5057600080fd5b614b5989614847565b9750614b6760208a01614847565b9650614b7560408a01614847565b9550614b8360608a01614847565b9450614b9160808a01614847565b9350614b9f60a08a01614847565b9250614bad60c08a01614847565b9150614bbb60e08a01614847565b90509295985092959890939650565b806060810183101561096457600080fd5b600060608284031215614bed57600080fd5b6123fa8383614bca565b600082601f830112614c0857600080fd5b8135602067ffffffffffffffff821115614c2457614c24614863565b8160051b614c338282016148a2565b9283528481018201928281019087851115614c4d57600080fd5b83870192505b84831015614c6c57823582529183019190830190614c53565b979650505050505050565b600080600080600060a08688031215614c8f57600080fd5b614c9886614847565b9450614ca660208701614847565b9350604086013567ffffffffffffffff80821115614cc357600080fd5b614ccf89838a01614bf7565b94506060880135915080821115614ce557600080fd5b614cf189838a01614bf7565b93506080880135915080821115614d0757600080fd5b50614d14888289016148d3565b9150509295509295909350565b80151581146112aa57600080fd5b600060208284031215614d4157600080fd5b81356123fa81614d21565b60008060c08385031215614d5f57600080fd5b614d698484614bca565b9150614d788460608501614bca565b90509250929050565b600080600080600060608688031215614d9957600080fd5b8535614da481614ade565b9450602086013567ffffffffffffffff80821115614dc157600080fd5b614dcd89838a01614761565b90965094506040880135915080821115614de657600080fd5b50614df388828901614761565b969995985093965092949392505050565b600080600060608486031215614e1957600080fd5b8335614e2481614ade565b92506020840135614e3481614ade565b91506040840135614e4481614ade565b809150509250925092565b634e487b7160e01b600052602160045260246000fd5b60038110614e8357634e487b7160e01b600052602160045260246000fd5b9052565b602081016109648284614e65565b600080600080600060a08688031215614ead57600080fd5b614eb686614847565b9450614ec460208701614847565b93506040860135925060608601359150608086013567ffffffffffffffff811115614eee57600080fd5b614d14888289016148d3565b60208082526014908201527310dbdb9d1c9858dd1cc8185c995b89dd081cd95d60621b604082015260600190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252600b908201526a456d70747920617272617960a81b604082015260600190565b6020808252600c908201526b4e6f20636f6e74726163747360a01b604082015260600190565b600060208284031215614faf57600080fd5b81516123fa81614d21565b634e487b7160e01b600052603260045260246000fd5b6020808252601190820152702737ba1037bbb732b210313c903ab9b2b960791b604082015260600190565b80516006811061485e57600080fd5b805161485e81614ade565b600082601f83011261502657600080fd5b60405160c0810181811067ffffffffffffffff8211171561504957615049614863565b6040528060c084018581111561505e57600080fd5b845b8181101561508157805161507381614ade565b835260209283019201615060565b509195945050505050565b6000610180828403121561509f57600080fd5b6150a7614879565b82516150b281614a46565b81526020830151600a81106150c657600080fd5b60208201526150d760408401614ffb565b60408201526150e86060840161500a565b60608201526150f96080840161500a565b608082015261510b8460a08501615015565b60a0820152610160929092015160c083015250919050565b634e487b7160e01b600052601160045260246000fd5b600060001982141561514d5761514d615123565b5060010190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601290820152712737ba1030b236b4b71037b91037bbb732b960711b604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60006020828403121561521557600080fd5b81356123fa81614ade565b600060ff821660ff84168082101561523a5761523a615123565b90039392505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60006020828403121561527957600080fd5b5051919050565b6000821982111561529357615293615123565b500190565b828152604081016123fa6020830184614e65565b60008160001904831182151516156152c6576152c6615123565b500290565b6000828210156152dd576152dd615123565b500390565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b03939093168352602083019190915260ff16604082015260600190565b60008261533957634e487b7160e01b600052601260045260246000fd5b500690565b600060ff821660ff81141561535557615355615123565b60010192915050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fea2646970667358221220e38a0fd119dae9b7450f51cb2d2f30d740c1d4913d0e2e85e2d26a00aa78b59564736f6c63430008090033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.