Source Code
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers.
Latest 19 internal transactions
Advanced mode:
| Parent Transaction Hash | Block | From | To | ||||
|---|---|---|---|---|---|---|---|
| 10460563 | 489 days ago | 0 FRAX | |||||
| 10460536 | 489 days ago | 0 FRAX | |||||
| 10258481 | 494 days ago | 0 FRAX | |||||
| 10258481 | 494 days ago | 0 FRAX | |||||
| 10258481 | 494 days ago | 0 FRAX | |||||
| 10258481 | 494 days ago | 0 FRAX | |||||
| 10258481 | 494 days ago | 0 FRAX | |||||
| 10235191 | 495 days ago | 0 FRAX | |||||
| 10235186 | 495 days ago | 0 FRAX | |||||
| 10235181 | 495 days ago | 0 FRAX | |||||
| 10235176 | 495 days ago | 0 FRAX | |||||
| 10235167 | 495 days ago | 0 FRAX | |||||
| 10235149 | 495 days ago | 0 FRAX | |||||
| 10235128 | 495 days ago | 0 FRAX | |||||
| 10235108 | 495 days ago | 0 FRAX | |||||
| 10235087 | 495 days ago | 0 FRAX | |||||
| 10235020 | 495 days ago | 0 FRAX | |||||
| 10234961 | 495 days ago | 0 FRAX | |||||
| 10201381 | 495 days ago | 0 FRAX |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
QuestTracker
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 100000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
/**
* ====================================================================
* | ______ _______ |
* | / _____________ __ __ / ____(_____ ____ _____ ________ |
* | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
* | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
* | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
* | |
* ====================================================================
* ========================= QuestTracker =============================
* ====================================================================
* Frax Finance: https://github.com/FraxFinance
*/
import { QuestTrackerAccessControl } from "./QuestTrackerAccessControl.sol";
/**
* @title QuestTracker
* @author Frax Finance
* @notice The QuestTracker contract is used to track quests and their progress for users.
*/
contract QuestTracker is QuestTrackerAccessControl {
/**
* @notice This struct represents a quest.
*/
struct Quest {
uint256 reward; // The amount of FXTL points awarded for completing the quest - 32 bytes: slot 1
uint256 startBlock; // The start block of the quest - marks the first block that compleion conditions apply - 32 bytes: slot 2
uint256 endBlock; // The end block of the quest - marks the last block that completion conditions apply - 32 bytes : slot 3
string title; // The title of the quest - own slot: slot 4
string description; // The URI to the quest description - own slot: slot 5
uint64 experiencePoints; // The amount of experience points earned for completing the quest - 8 bytes: slot 6 (24 bytes remaining)
QuestStatus status; // The status of the quest (Pending, Upcoming, Active, Expired) - 1 byte: slot 6 (23 bytes remaining)
QuestType questType; // The type of the quest (Single, Recursive, Limited) - 1 byte: slot 6 (22 bytes remaining)
uint128 maxCompletions; // The maximum number of users that can complete the quest - 16 bytes: slot 6 (6 bytes remaining)
uint64 recursiveCooldown; // The cooldown period between completions of the recursive quest - 8 bytes: slot 7 (24 bytes remaining)
bool selfServeCompletion; // Whether the quest can be completed by the user or not. If true, it needs QuestValidator - 1 byte: slot 7 (23 bytes remaining)
address questValidator; // The address of the contract that validates the quest completion - 20 bytes: slot 7 (3 bytes remaining)
uint256[50] __gap; // Reserved storage gap to prevent storage collisions
}
/**
* @notice This struct represents the status of a user's progress on a quest.
*/
struct UserData {
uint256 numberOfCompletedQuests; // The number of quests completed by the user - 32 bytes: slot 1
uint256 lifetimePoints; // The total amount of FXTL points earned by the user - 32 bytes: slot 2
uint64 lifetimeExperienceEarned; // The total amount of experience points earned by the user - 8 bytes: slot 3 (24 bytes remaining)
uint64 currentLevelExperiencePoints; // The amount of experience points earned since the last level up - 8 bytes: slot 3 (16 bytes remaining)
uint64 currentLevel; // The current level of the user - 8 bytes: slot 3 (8 bytes remaining)
uint256[50] __gap; // Reserved storage gap to prevent storage collisions
}
/**
* @notice This struct represents the status of a user's progress on a recursive quest.
*/
struct RecursiveQuestCompletions {
uint128 totalCompletions; // The total number of times the user has completed the quest - 16 bytes: slot 1 (16 bytes remaining)
uint128 unallocatedCompletions; // The number of completions that have not yet been allocated - 16 bytes: slot 1 (0 bytes remaining)
uint128 lastCompletionTimestamp; // The timestamp of the last completion of the quest - 16 bytes: slot 2 (16 bytes remaining)
uint256[50] __gap; // Reserved storage gap to prevent storage collisions
}
/**
* @notice This mapping is used to keep track of the number of times a quest has been completed.
* @dev questId ID of the quest
* @dev timesCompleted Number of times the quest has been completed
*/
mapping(uint256 questId => uint128 timesCompleted) public limitedQuestCompletions;
/**
* @notice This mapping is used to keep track of all of the quests.
* @dev The quests are stored using their unique ID.
* @dev questId ID of the quest
* @dev quest The quest being stored
*/
mapping(uint256 questId => Quest quest) private _quests;
/**
* @notice This mapping is used to keep track of users progress on recursive quests.
* @dev The mapping is used to add the ability to implement a cooldown period between completions, so that the users
* can't spam recursive quests.
* @dev user Address of the user
* @dev questId ID of the quest
* @dev questCompletions The struct containing the user's limited progress on the recursive quest
*/
mapping(address user => mapping(uint256 questId => RecursiveQuestCompletions questCompletions))
private _recursiveQuestCompletions;
/**
* @notice This mapping represents the status of a user's progress on a quest.
* @dev Tracking the users progress through quest allows for allocation of awards upon completion of the quest.
* @dev user Address of the user
* @dev questId ID of the quest
* @dev status Status of the user's progress on the quest
*/
mapping(address user => mapping(uint256 questId => UserQuestStatus status)) public userQuestStatus;
/**
* @notice This mapping is used to keep track of the users' quest progress.
* @dev user Address of the user
* @dev data The UserData struct containing the user's quest progress
*/
mapping(address user => UserData userData) private _userQuestProgress;
/**
* @notice This mapping is used to keep track of the quests completed by the user.
* @dev This is an unordered list and serves the purpose of tracking the user's progress for off-chain processing.
* @dev user Address of the user
* @dev completedQuestId ID of the quest completed by the user
*/
mapping(address user => mapping(uint256 questIndex => uint256 completedQuestId)) public completedQuestIds;
/// ID of the next quest to be added as well as the total number of quests.
uint256 public nextQuestId;
/// Flag to determine if the contract has been initialized.
bool public initialized;
/// Base amount of experience points required to level up from level 1 to level 2.
uint64 public baseExperiencePoints;
/// Increment of experience points required to level up.
uint64 public experiencePointsIncrement;
/**
* @notice Initialize the QuestTracker and set the owner.
* @param owner Address of the owner of the contract
*/
function initialize(address owner) public override {
if (initialized) revert AlreadyInitialized();
baseExperiencePoints = 100;
experiencePointsIncrement = 50;
super.initialize(owner);
initialized = true;
}
/**
* @notice Used to retrieve the number of times the quest can still be completed.
* @param questId ID of the quest to check for the remaining compleations
* @return remainingCompletions The number of times the quest can still be completed
*/
function remainingLimitedQuestCompletions(uint256 questId) public view returns (uint256 remainingCompletions) {
if (_quests[questId].questType == QuestType.Limited) {
remainingCompletions = _quests[questId].maxCompletions - limitedQuestCompletions[questId];
} else {
remainingCompletions = 2 ** 256 - 1;
}
}
/**
* @notice Used to retrieve the desired quest.
* @param questId ID of the quest to retrieve
* @return quest The quest being retrieved
*/
function quests(uint256 questId) public view returns (Quest memory quest) {
return _quests[questId];
}
/**
* @notice Used to retrieve the progress statistics of a user.
* @param user Address of the user to retrieve the progress statistics for
* @return userData The UserData struct containing the user's quests progress
*/
function userQuestProgress(address user) public view returns (UserData memory userData) {
return _userQuestProgress[user];
}
/**
* @notice Used to retrieve the information about the user's progress on a specific recursive quest.
* @dev If the quest ID used is for a non-recursive quest, the function will return a struct with all fields set to 0.
* @param user Address of the user to retrieve the progress statistics for
* @param questId ID of the quest to retrieve the progress statistics for
* @return questCompletions The RecursiveQuestCompletions struct containing the user's progress on the recursive quest
*/
function recursiveQuestCompletions(
address user,
uint256 questId
) public view returns (RecursiveQuestCompletions memory questCompletions) {
return _recursiveQuestCompletions[user][questId];
}
function getUserLevel(address user) public view returns (uint64) {
if (_userQuestProgress[user].currentLevel == 0) {
return 1;
} else {
return _userQuestProgress[user].currentLevel;
}
}
function getRequiredExperienceForNextLevel(uint64 currentUserLevel) public view returns (uint64) {
if (currentUserLevel == 0) revert InvalidLevel();
uint64 expereincePointsRequired = baseExperiencePoints + ((currentUserLevel - 1) * experiencePointsIncrement);
return expereincePointsRequired;
}
/**
* @notice Used to add a new quest to the tracker.
* @dev This can only be called by the Flox contributors.
* @param reward Amount of FXTL received upon completion of the quest
* @param startBlock Block number of the block at which the quest starts
* @param endBlock Block number of the block at which the quest ends
* @param title The title of the quest
* @param description The URI to the quest description
* @param experiencePoints Amount of experience points earned for completing the quest
* @param questType The type of the quest (Single, Recursive, Limited), defaults to Single
* @param maxCompletions The maximum number of users that can complete the quest
* @param recursiveCooldown The cooldown period between completions of the recursive quest
* @param selfServeCompletion Whether the quest can be completed by the user or not. If true, it needs QuestValidator
* @param questValidator The address of the contract that validates the quest completion
*/
function addQuest(
uint256 reward,
uint256 startBlock,
uint256 endBlock,
string memory title,
string memory description,
uint64 experiencePoints,
QuestType questType,
uint128 maxCompletions,
uint64 recursiveCooldown,
bool selfServeCompletion,
address questValidator
) external {
_onlyFloxContributor();
if (startBlock > endBlock) revert InvalidBlockRange();
QuestStatus status;
if (block.number < startBlock) {
status = QuestStatus.Upcoming;
} else if (block.number < endBlock) {
status = QuestStatus.Active;
} else {
status = QuestStatus.Expired;
}
questType = questType == QuestType.Unset ? QuestType.Single : questType;
maxCompletions = questType == QuestType.Limited ? maxCompletions : 0;
recursiveCooldown = questType == QuestType.Recursive ? recursiveCooldown : 0;
questValidator = selfServeCompletion ? questValidator : address(0);
if (selfServeCompletion && questValidator == address(0)) revert InvalidQuestValidator();
uint256[50] memory dummy;
_quests[nextQuestId] = Quest({
reward: reward,
startBlock: startBlock,
endBlock: endBlock,
experiencePoints: experiencePoints,
title: title,
description: description,
status: status,
questType: questType,
maxCompletions: maxCompletions,
recursiveCooldown: recursiveCooldown,
selfServeCompletion: selfServeCompletion,
questValidator: questValidator,
__gap: dummy
});
nextQuestId++;
emit QuestAdded(nextQuestId - 1, reward, startBlock, endBlock);
emit QuestValidatorUpdated(nextQuestId - 1, selfServeCompletion, questValidator);
}
/**
* @notice Used to update an existing quest.
* @dev Passing an empty value for any of the parameters will result in the value not being updated.
* @dev This can only be called by the Flox contributors.
* @param questId ID of the quest to update
* @param updatedReward New amount of FXTL received upon completion of the quest
* @param updatedStartBlock New block number at which the quest starts
* @param updatedEndBlock New block number at which the quest ends
* @param updatedTitle New title of the quest
* @param updatedDescription New URI to the quest description
* @param updatedExperiencePoints New amount of experience points earned for completing the quest
* @param updatedQuestType New type of the quest (Single, Recursive, Limited)
* @param updatedMaxCompletions New maximum number of users that can complete the quest
*/
function updateQuest(
uint256 questId,
uint256 updatedReward,
uint256 updatedStartBlock,
uint256 updatedEndBlock,
string memory updatedTitle,
string memory updatedDescription,
uint64 updatedExperiencePoints,
QuestType updatedQuestType,
uint128 updatedMaxCompletions,
uint64 updatedRecursiveCooldown
) external {
_onlyFloxContributor();
if (questId >= nextQuestId) revert QuestDoesNotExist();
Quest memory quest = _quests[questId];
updatedReward = updatedReward == 0 ? quest.reward : updatedReward;
updatedStartBlock = updatedStartBlock == 0 ? quest.startBlock : updatedStartBlock;
updatedEndBlock = updatedEndBlock == 0 ? quest.endBlock : updatedEndBlock;
updatedExperiencePoints = updatedExperiencePoints == 0 ? quest.experiencePoints : updatedExperiencePoints;
updatedTitle = bytes(updatedTitle).length == 0 ? quest.title : updatedTitle;
updatedDescription = bytes(updatedDescription).length == 0 ? quest.description : updatedDescription;
updatedQuestType = updatedQuestType == QuestType.Unset ? quest.questType : updatedQuestType;
if (updatedQuestType != QuestType.Limited) {
updatedMaxCompletions = 0;
} else if (updatedMaxCompletions == uint128(0)) {
updatedMaxCompletions = quest.maxCompletions;
}
if (updatedQuestType != QuestType.Recursive) {
updatedRecursiveCooldown = 0;
} else if (updatedRecursiveCooldown == uint64(0)) {
updatedRecursiveCooldown = quest.recursiveCooldown;
}
if (updatedStartBlock > updatedEndBlock) revert InvalidBlockRange();
QuestStatus updatedStatus;
if (block.number < updatedStartBlock) {
updatedStatus = QuestStatus.Upcoming;
} else if (block.number < updatedEndBlock) {
updatedStatus = QuestStatus.Active;
} else {
updatedStatus = QuestStatus.Expired;
}
uint256[50] memory dummy;
_quests[questId] = Quest({
reward: updatedReward,
startBlock: updatedStartBlock,
endBlock: updatedEndBlock,
experiencePoints: updatedExperiencePoints,
title: updatedTitle,
description: updatedDescription,
status: updatedStatus,
questType: updatedQuestType,
maxCompletions: updatedMaxCompletions,
recursiveCooldown: updatedRecursiveCooldown,
selfServeCompletion: quest.selfServeCompletion,
questValidator: quest.questValidator,
__gap: dummy
});
emit QuestUpdated(questId, updatedReward, updatedStartBlock, updatedEndBlock, updatedStatus);
}
/**
* @notice Used to update the quest validator settings for a quest.
* @param questId ID of the quest to update the validator for
* @param allowSelfServeCompletion Whether the quest can be completed by the user or not. If true, it needs
* QuestValidator
* @param questValidator Address of the quest validator smart contract for the quest
*/
function manageQuestValidator(uint256 questId, bool allowSelfServeCompletion, address questValidator) external {
_onlyFloxContributor();
if (questId >= nextQuestId) revert QuestDoesNotExist();
Quest storage quest = _quests[questId];
if (quest.selfServeCompletion == allowSelfServeCompletion && quest.questValidator == questValidator) {
revert SameValidatorSettings();
}
if (allowSelfServeCompletion && questValidator == address(0)) revert InvalidQuestValidator();
quest.selfServeCompletion = allowSelfServeCompletion;
if (!allowSelfServeCompletion) {
quest.questValidator = address(0);
} else {
quest.questValidator = questValidator;
}
emit QuestValidatorUpdated(questId, quest.selfServeCompletion, quest.questValidator);
}
/**
* @notice Used to update the status of a user's quest.
* @dev This can only be called by the contributors of the quest of Flox contributors.
* @dev Setting a `Recursive` quest as `Allocated` will only mark one completed instance as allocated. To mark
* multiple instances as allocated, the `Allocated` status must be set multiple times.
* @param questId ID of the quest being updated
* @param user Address of the user receiving the quest status update
* @param status Status of the user's quest progress after the update
*/
function updateUserQuestStatus(uint256 questId, address user, UserQuestStatus status) external {
_onlyContributor(questId);
if (questId >= nextQuestId) revert QuestDoesNotExist();
if (status <= userQuestStatus[user][questId] && _quests[questId].questType != QuestType.Recursive) {
revert InvalidUserQuestStatusUpdate(userQuestStatus[user][questId], status);
}
_updateUserQuestProgress(questId, user, status);
emit UserQuestStatusUpdated(user, questId, status);
}
/**
* @notice Used to update the status of a user's quest progress for multiple quests and various progress statuses.
* @dev Each status will be applied to the corresponding quest ID.
* @dev This can only be called by the Flox contributors.
* @dev Setting a `Recursive` quest as `Allocated` will only mark one completed instance as allocated. To mark
* multiple instances as allocated, the `Allocated` status must be set multiple times.
* @param questIds IDs of the quests being updated
* @param user Address of the user receiving the quest status updates
* @param statuses Statuses of the user's quest progress after the update
*/
function bulkUpdateSingleUserQuestStatuses(
uint256[] memory questIds,
address user,
UserQuestStatus[] memory statuses
) external {
_onlyFloxContributor();
if (questIds.length != statuses.length) revert ArrayLengthMismatch();
for (uint256 i; i < questIds.length; ) {
if (questIds[i] >= nextQuestId) revert QuestDoesNotExist();
if (statuses[i] <= userQuestStatus[user][questIds[i]]) {
revert InvalidUserQuestStatusUpdate(userQuestStatus[user][questIds[i]], statuses[i]);
}
_updateUserQuestProgress(questIds[i], user, statuses[i]);
emit UserQuestStatusUpdated(user, questIds[i], statuses[i]);
unchecked {
++i;
}
}
}
/**
* @notice Used to update the status of multiple users' progresses in a single quest.
* @dev This can only be called by the contributors of the quest or Flox contributors.
* @param questId ID of the quest being updated
* @param users Addresses of the users receiving the quest status updates
* @param status New status assigned to the users' progress on the quest
*/
function bulkUpdateMultipleUsersQuestStatus(
uint256 questId,
address[] memory users,
UserQuestStatus status
) external {
_onlyContributor(questId);
if (questId >= nextQuestId) revert QuestDoesNotExist();
for (uint256 i; i < users.length; ) {
if (status <= userQuestStatus[users[i]][questId]) {
revert InvalidUserQuestStatusUpdate(userQuestStatus[users[i]][questId], status);
}
_updateUserQuestProgress(questId, users[i], status);
emit UserQuestStatusUpdated(users[i], questId, status);
unchecked {
++i;
}
}
}
/**
* @notice Used to update the status of multiple users' progresses in multiple quests.
* @dev The status at each index will be applied to the corresponding user and quest ID.
* @dev This can only be called by the Flox contributors.
* @dev Setting a `Recursive` quest as `Allocated` will only mark one completed instance as allocated. To mark
* multiple instances as allocated, the `Allocated` status must be set multiple times.
* @param questIds IDs of the quests being updated
* @param users Addresses of the users receiving the quest status updates
* @param statuses Quest progress statuses of the users after the update
*/
function bulkUpdateMultipleUsersQuestsStatuses(
uint256[] memory questIds,
address[] memory users,
UserQuestStatus[] memory statuses
) external {
_onlyFloxContributor();
if (users.length != questIds.length) revert ArrayLengthMismatch();
if (questIds.length != statuses.length) revert ArrayLengthMismatch();
for (uint256 i; i < users.length; ) {
if (questIds[i] >= nextQuestId) revert QuestDoesNotExist();
if (statuses[i] <= userQuestStatus[users[i]][questIds[i]]) {
revert InvalidUserQuestStatusUpdate(userQuestStatus[users[i]][questIds[i]], statuses[i]);
}
_updateUserQuestProgress(questIds[i], users[i], statuses[i]);
emit UserQuestStatusUpdated(users[i], questIds[i], statuses[i]);
unchecked {
++i;
}
}
}
/**
* @notice Used to update the status of a user's progress on a quest.
* @dev Once the quest progress status transitions from `Incomplete` to anything else, the experience points for it
* are allocated to the user.
* @dev Once the quest progress status transitions to `Allocated`, the reward earned for completing the quest is
* credited to the user's data.
* @dev `Recursive` quests can only be marked as `Allocated` if there are unallocated completions.
* @param questId ID of the quest being updated
* @param user Address of the user receiving the quest status update
* @param status New status assigned to the user's progress on the quest
*/
function _updateUserQuestProgress(uint256 questId, address user, UserQuestStatus status) internal {
Quest storage quest = _quests[questId];
QuestType questType = quest.questType;
UserQuestStatus currentQuestStatus = userQuestStatus[user][questId];
if (questType == QuestType.Limited) {
if (
limitedQuestCompletions[questId] >= quest.maxCompletions &&
currentQuestStatus != UserQuestStatus.PendingAllocation
) {
revert MaximumNumberOfCompletionsReached();
}
}
if (questType == QuestType.Recursive) {
uint64 cooldown = quest.recursiveCooldown;
if (
_recursiveQuestCompletions[user][questId].lastCompletionTimestamp + uint256(cooldown) > block.timestamp
) {
revert CooldownStillActive();
}
if (
status == UserQuestStatus.Allocated &&
_recursiveQuestCompletions[user][questId].unallocatedCompletions == 0
) {
revert NoRecursiveQuestPendingAllocations();
}
}
if (
currentQuestStatus == UserQuestStatus.Incomplete ||
(questType == QuestType.Recursive && status == UserQuestStatus.PendingAllocation)
) {
completedQuestIds[user][_userQuestProgress[user].numberOfCompletedQuests] = questId;
_userQuestProgress[user].numberOfCompletedQuests++;
_allocateUserExperiencePoints(user, quest.experiencePoints);
if (questType == QuestType.Recursive) {
_recursiveQuestCompletions[user][questId].totalCompletions++;
_recursiveQuestCompletions[user][questId].unallocatedCompletions++;
_recursiveQuestCompletions[user][questId].lastCompletionTimestamp = uint128(block.timestamp);
} else if (questType == QuestType.Limited) {
limitedQuestCompletions[questId]++;
if (
currentQuestStatus == UserQuestStatus.Incomplete &&
limitedQuestCompletions[questId] >= quest.maxCompletions
) {
quest.status = QuestStatus.Expired;
quest.endBlock = block.number;
emit QuestUpdated(questId, quest.reward, quest.startBlock, block.number, QuestStatus.Expired);
}
}
}
if (status == UserQuestStatus.Allocated) {
_userQuestProgress[user].lifetimePoints += quest.reward;
if (questType == QuestType.Recursive) {
_recursiveQuestCompletions[user][questId].unallocatedCompletions--;
}
}
userQuestStatus[user][questId] = status;
}
function _allocateUserExperiencePoints(address user, uint64 experiencePoints) internal {
UserData storage userData = _userQuestProgress[user];
userData.lifetimeExperienceEarned += experiencePoints;
userData.currentLevelExperiencePoints += experiencePoints;
if (userData.currentLevel == 0) {
userData.currentLevel = 1;
}
uint64 requiredLevelUpExperience = getRequiredExperienceForNextLevel(userData.currentLevel);
while (userData.currentLevelExperiencePoints >= requiredLevelUpExperience) {
userData.currentLevelExperiencePoints -= requiredLevelUpExperience;
userData.currentLevel++;
emit UserLeveledUp(user, userData.currentLevel);
requiredLevelUpExperience = getRequiredExperienceForNextLevel(userData.currentLevel);
}
}
/// Storage gap to prevent storage collisions.
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
/**
* ====================================================================
* | ______ _______ |
* | / _____________ __ __ / ____(_____ ____ _____ ________ |
* | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
* | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
* | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
* | |
* ====================================================================
* =================== QuestTrackerAccessControl ======================
* ====================================================================
* Frax Finance: https://github.com/FraxFinance
*/
import { IQuestTrackerEvents } from "./IQuestTrackerEvents.sol";
/**
* @title QuestTrackerAccessControl
* @author Frax Finance
* @notice The QuestTrackerAccessControl contract is used to power the access control of the QuestTracker smart contract.
*/
contract QuestTrackerAccessControl is IQuestTrackerEvents {
/// Address of the owner of the contract.
address public owner;
/// Address of the nominated owner of the contract.
address public nominatedOwner;
/**
* @notice Used to track Flox contributors.
* @dev contributor Address of the contributor
* @dev isContributor Status of the contributor
*/
mapping(address contributor => bool isContributor) public floxContributors;
/**
* @notice Used to track contributors for specific quests.
* @dev The quest contributors are used to manage the statuses of specific quests.
* @dev questId ID of the quest
* @dev questContibutor Address of the quest contributor
* @dev isContributor Status of the quest contributor
*/
mapping(uint256 questId => mapping(address questContibutor => bool isContributor)) public questContributors;
/**
* @notice Used to initialize the smart contract and set the owner.
* @param _owner Address of the owner of the contract
*/
function initialize(address _owner) public virtual {
if (owner != address(0)) revert AlreadyInitialized();
owner = _owner;
}
/**
* @notice Used to restrict function execution to calls initiated by the owner.
*/
modifier onlyOwner() {
if (msg.sender != owner) revert NotOwner();
_;
}
/**
* @notice Nominate a new owner for the contract.
* @dev Only the current owner can nominate a new owner.
* @param _owner Address of the new owner
*/
function nominateNewOwner(address _owner) external onlyOwner {
nominatedOwner = _owner;
emit OwnerNominated(_owner);
}
/**
* @notice Accept the ownership of the contract.
* @dev Only the nominated owner can accept the ownership.
*/
function acceptOwnership() external {
if (msg.sender != nominatedOwner) revert NotNominatedOwner();
address oldOwner = owner;
owner = nominatedOwner;
nominatedOwner = address(0);
emit OwnerChanged(oldOwner, owner);
}
/**
* @notice Manage Flox contributors.
* @dev Flox contributor is allowed to manage all quests as well as their progress status for every user.
* @param _contributor Address of the contributor to manage
* @param _isContributor Status to assign the contributor. `false` to remove, `true` to add.
*/
function manageFloxContributors(address _contributor, bool _isContributor) external onlyOwner {
if (floxContributors[_contributor] == _isContributor) revert SameContributorStatus();
floxContributors[_contributor] = _isContributor;
emit FloxContributorUpdate(_contributor, _isContributor);
}
/**
* @notice Update the specific contributor for a quest.
* @dev Only the owner can call this function.
* @dev We allow multiple contributors for a single quest, so that we support the possibility of automatic quest
* status updates as well as dedicated validators of quest completion to work in synergy.
* @param _questId ID of the quest we are configuring the specific contibutor for.
* @param _contributor Address of the quest contributor being managed
* @param _isContributor Status to assign the contributor. `false` to remove, `true` to add.
*/
function updateQuestContributor(uint256 _questId, address _contributor, bool _isContributor) external onlyOwner {
if (questContributors[_questId][_contributor] == _isContributor) revert SameContributorStatus();
questContributors[_questId][_contributor] = _isContributor;
emit QuestContributorUpdate(_questId, _contributor, _isContributor);
}
/**
* @notice Used to restrict function execution to calls initiated by a Quest contributor.
* @param _questId ID of the quest to check the quest contributor status for
*/
function _onlyQuestContributor(uint256 _questId) internal view {
if (!questContributors[_questId][msg.sender]) revert NotQuestContributor();
}
/**
* @notice Used to restrict function execution to calls initiated by a Flox contributor.
*/
function _onlyFloxContributor() internal view {
if (!floxContributors[msg.sender]) revert NotFloxContributor();
}
/**
* @notice Used to restrict function execution to calls initiated by a Flox or Quest contributor.
* @param _questId ID of the quest to check the quest contributor status for
*/
function _onlyContributor(uint256 _questId) internal view {
if (!floxContributors[msg.sender] && !questContributors[_questId][msg.sender]) {
revert NotFloxOrQuestContributor();
}
}
/// Storage gap to prevent storage collisions.
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
/**
* ====================================================================
* | ______ _______ |
* | / _____________ __ __ / ____(_____ ____ _____ ________ |
* | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
* | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
* | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
* | |
* ====================================================================
* ======================== IQuestTrackerEvents =======================
* ====================================================================
* Frax Finance: https://github.com/FraxFinance
*/
import { IQuestTrackerErrors } from "./IQuestTrackerErrors.sol";
/**
* @title IQuestTrackerEvents
* @author Frax Finance
* @notice A collection of events used by the Flox Quest tracker system.
*/
contract IQuestTrackerEvents is IQuestTrackerErrors {
/**
* @notice Emitted when the Flox contributor status is updated.
* @param contributor Address of the cintributor being updated
* @param isContributor New status assigned to the contributor
*/
event FloxContributorUpdate(address contributor, bool isContributor);
/**
* @notice Emitted when the ownership of the contract is transferred.
* @param oldOwner Address of the previous owner
* @param newOwner Address of the new owner
*/
event OwnerChanged(address oldOwner, address newOwner);
/**
* @notice Emitted when a new owner is nominated.
* @param newOwner Address of the account nominated to be the new owner
*/
event OwnerNominated(address newOwner);
/**
* @notice Emitted when a user levels up.
* @param user Address of the user leveling up
* @param level New level assigned to the user
*/
event UserLeveledUp(address indexed user, uint256 indexed level);
/**
* @notice Emitted when a user's progress on a quest is updated.
* @param user Address of the user receiving the quest status update
* @param questId ID of the quest being updated
* @param status New status assigned to the user's progress on the quest
*/
event UserQuestStatusUpdated(address indexed user, uint256 indexed questId, UserQuestStatus status);
/**
* @notice Emitted when a new quest is added.
* @param questId ID of the quest being added
* @param reward Amount of FXTL received upon completion of the quest
* @param startBlock Block at which the quest starts
* @param endBlock Block at which the quest ends
*/
event QuestAdded(uint256 indexed questId, uint256 reward, uint256 startBlock, uint256 endBlock);
/**
* @notice Emitted when the quest contributor status is updated.
* @param questId ID of the quest receiving the contributor update
* @param contributor Address of the contributor being updated
* @param isContributor New status assigned to the contributor
*/
event QuestContributorUpdate(uint256 questId, address contributor, bool isContributor);
/**
* @notice Emitted when a quest is updated.
* @param questId ID of the quest being updated
* @param reward Amount of FXRTL received upon completion of the quest
* @param startBlock Block number at which the quest starts
* @param endBlock BlockNumber at which the quest starts
* @param status Status of the quest after the update
*/
event QuestUpdated(
uint256 indexed questId,
uint256 reward,
uint256 startBlock,
uint256 endBlock,
QuestStatus status
);
/**
* @notice Emitted when the validator settings of a quest are updated.
* @param questId ID of the quest that had validator settings updated
* @param allowsSelfValidation Whether the quest allows self-validation
* @param validator Address of the validator smart contract for the quest
*/
event QuestValidatorUpdated(uint256 indexed questId, bool allowsSelfValidation, address indexed validator);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
/**
* ====================================================================
* | ______ _______ |
* | / _____________ __ __ / ____(_____ ____ _____ ________ |
* | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
* | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
* | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
* | |
* ====================================================================
* ======================== IQuestTrackerErrors =======================
* ====================================================================
* Frax Finance: https://github.com/FraxFinance
*/
import { IQuestTrackerEnums } from "./IQuestTrackerEnums.sol";
/**
* @title IQuestTrackerErrors
* @author Frax Finance
* @notice A collection of events used by the Flox Quest tracker system.
*/
contract IQuestTrackerErrors is IQuestTrackerEnums {
/// Returned if the smart contract is already initialized
error AlreadyInitialized();
/// Returned if the length of the arrays passed to a function do not match.
error ArrayLengthMismatch();
/// Returned if the cooldown period of the Recursive quest is still active.
error CooldownStillActive();
/// Returned if the start block is greater than the end block.
error InvalidBlockRange();
/// Returned if the quest level is invalid.
error InvalidLevel();
/// Returned if the quest validator address is set to the zero address if the self validation is permitted.
error InvalidQuestValidator();
/**
* @notice Returned if the user quest status update is invalid.
* @param currentStatus The current status of the user's progress on the quest
* @param attemptedStatus The status attempted to be assigned to the user's progress on the quest
*/
error InvalidUserQuestStatusUpdate(UserQuestStatus currentStatus, UserQuestStatus attemptedStatus);
/// Signifies that the Limited quest has been completed the maximum number of times.
error MaximumNumberOfCompletionsReached();
/// Signifies that the recursive quest has no pending allocations.
error NoRecursiveQuestPendingAllocations();
/// Signifies that the caller is not a Flox contributor.
error NotFloxContributor();
/// Signifies tht the caller is neiter a Flox or Quest contributor.
error NotFloxOrQuestContributor();
/// Signifies that the caller is not the nominated owner.
error NotNominatedOwner();
/// Signifies that the caller is not the owner.
error NotOwner();
/// Signifies that the caller is not the quest contributor.
error NotQuestContributor();
/// Returned if the quest being accessed does not exist.
error QuestDoesNotExist();
/// Signifies that the attempted status change is the same as the preexisting status.
error SameContributorStatus();
/// Signifies that the attempted quest validator settings updates are the same as the preexisting settings.
error SameValidatorSettings();
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
/**
* ====================================================================
* | ______ _______ |
* | / _____________ __ __ / ____(_____ ____ _____ ________ |
* | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
* | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
* | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
* | |
* ====================================================================
* ===================== IQuestTrackerEnums ===========================
* ====================================================================
* Frax Finance: https://github.com/FraxFinance
*/
/**
* @title IQuestTrackerEnums
* @author Frax Finance
* @notice A collection of enums used by the Flox Quest tracker system.
*/
contract IQuestTrackerEnums {
/**
* @notice This enum represents the global status of a quest.
*/
enum QuestStatus {
Pending, // 0; Quest has not yet been added or fully defined
Upcoming, // 1; Quest is defined but not yet active (the starting block is in the future)
Active, // 2; Quest is currently active and can be completed by the users in order to earn rewards
Expired // 3; Quest is no longer active and can no longer be completed by the users
}
/**
* @notice This enum represents the type of a quest.
* @dev The Unset quest type is used to power the ability to update the quest type.
*/
enum QuestType {
Unset, // 0; Quest type has not yet been set
Single, // 1; Quest can only be completed once
Recursive, // 2; Quest can be completed multiple times
Limited // 3; Quest can be completed by a limited number of users
}
/**
* @notice This enum represents the status of a user's progress on a quest.
*/
enum UserQuestStatus {
Incomplete, // 0; User has not yet completed the quest
PendingAllocation, // 1; User has completed the quest but the reward has not yet been allocated
Allocated // 2; User has completed the quest and the reward has been allocated
}
}{
"remappings": [
"frax-std/=lib/frax-standard-solidity/src/",
"@eth-optimism/=lib/optimism/packages/",
"lib/optimism/packages/contracts-bedrock:src/=lib/optimism/packages/contracts-bedrock/src/",
"src/=src/",
"@openzeppelin-4/=node_modules/@openzeppelin-4/",
"@openzeppelin-5/=node_modules/@openzeppelin-5/",
"@openzeppelin/=node_modules/@openzeppelin/",
"@rari-capital/=node_modules/@rari-capital/",
"clones-with-immutable-args/=lib/optimism/packages/contracts-bedrock/lib/clones-with-immutable-args/src/",
"ds-test/=lib/frax-standard-solidity/lib/forge-std/lib/ds-test/src/",
"forge-std/=lib/frax-standard-solidity/lib/forge-std/src/",
"frax-standard-solidity/=lib/frax-standard-solidity/src/",
"kontrol-cheatcodes/=lib/optimism/packages/contracts-bedrock/lib/kontrol-cheatcodes/src/",
"lib-keccak/=lib/optimism/packages/contracts-bedrock/lib/lib-keccak/contracts/",
"openzeppelin-contracts-upgradeable/=lib/optimism/packages/contracts-bedrock/lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/optimism/packages/contracts-bedrock/lib/openzeppelin-contracts/",
"optimism/=lib/optimism/",
"safe-contracts/=lib/optimism/packages/contracts-bedrock/lib/safe-contracts/contracts/",
"solady/=lib/optimism/packages/contracts-bedrock/lib/solady/",
"solidity-bytes-utils/=lib/frax-standard-solidity/lib/solidity-bytes-utils/",
"solmate/=lib/optimism/packages/contracts-bedrock/lib/solmate/src/"
],
"optimizer": {
"enabled": true,
"runs": 100000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"ArrayLengthMismatch","type":"error"},{"inputs":[],"name":"CooldownStillActive","type":"error"},{"inputs":[],"name":"InvalidBlockRange","type":"error"},{"inputs":[],"name":"InvalidLevel","type":"error"},{"inputs":[],"name":"InvalidQuestValidator","type":"error"},{"inputs":[{"internalType":"enum IQuestTrackerEnums.UserQuestStatus","name":"currentStatus","type":"uint8"},{"internalType":"enum IQuestTrackerEnums.UserQuestStatus","name":"attemptedStatus","type":"uint8"}],"name":"InvalidUserQuestStatusUpdate","type":"error"},{"inputs":[],"name":"MaximumNumberOfCompletionsReached","type":"error"},{"inputs":[],"name":"NoRecursiveQuestPendingAllocations","type":"error"},{"inputs":[],"name":"NotFloxContributor","type":"error"},{"inputs":[],"name":"NotFloxOrQuestContributor","type":"error"},{"inputs":[],"name":"NotNominatedOwner","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"NotQuestContributor","type":"error"},{"inputs":[],"name":"QuestDoesNotExist","type":"error"},{"inputs":[],"name":"SameContributorStatus","type":"error"},{"inputs":[],"name":"SameValidatorSettings","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"contributor","type":"address"},{"indexed":false,"internalType":"bool","name":"isContributor","type":"bool"}],"name":"FloxContributorUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"questId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"QuestAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"questId","type":"uint256"},{"indexed":false,"internalType":"address","name":"contributor","type":"address"},{"indexed":false,"internalType":"bool","name":"isContributor","type":"bool"}],"name":"QuestContributorUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"questId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endBlock","type":"uint256"},{"indexed":false,"internalType":"enum IQuestTrackerEnums.QuestStatus","name":"status","type":"uint8"}],"name":"QuestUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"questId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"allowsSelfValidation","type":"bool"},{"indexed":true,"internalType":"address","name":"validator","type":"address"}],"name":"QuestValidatorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"level","type":"uint256"}],"name":"UserLeveledUp","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"questId","type":"uint256"},{"indexed":false,"internalType":"enum IQuestTrackerEnums.UserQuestStatus","name":"status","type":"uint8"}],"name":"UserQuestStatusUpdated","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"string","name":"title","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"uint64","name":"experiencePoints","type":"uint64"},{"internalType":"enum IQuestTrackerEnums.QuestType","name":"questType","type":"uint8"},{"internalType":"uint128","name":"maxCompletions","type":"uint128"},{"internalType":"uint64","name":"recursiveCooldown","type":"uint64"},{"internalType":"bool","name":"selfServeCompletion","type":"bool"},{"internalType":"address","name":"questValidator","type":"address"}],"name":"addQuest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"baseExperiencePoints","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"questId","type":"uint256"},{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"enum IQuestTrackerEnums.UserQuestStatus","name":"status","type":"uint8"}],"name":"bulkUpdateMultipleUsersQuestStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"questIds","type":"uint256[]"},{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"enum IQuestTrackerEnums.UserQuestStatus[]","name":"statuses","type":"uint8[]"}],"name":"bulkUpdateMultipleUsersQuestsStatuses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"questIds","type":"uint256[]"},{"internalType":"address","name":"user","type":"address"},{"internalType":"enum IQuestTrackerEnums.UserQuestStatus[]","name":"statuses","type":"uint8[]"}],"name":"bulkUpdateSingleUserQuestStatuses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"questIndex","type":"uint256"}],"name":"completedQuestIds","outputs":[{"internalType":"uint256","name":"completedQuestId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"experiencePointsIncrement","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"floxContributors","outputs":[{"internalType":"bool","name":"isContributor","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"currentUserLevel","type":"uint64"}],"name":"getRequiredExperienceForNextLevel","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserLevel","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"questId","type":"uint256"}],"name":"limitedQuestCompletions","outputs":[{"internalType":"uint128","name":"timesCompleted","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_contributor","type":"address"},{"internalType":"bool","name":"_isContributor","type":"bool"}],"name":"manageFloxContributors","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"questId","type":"uint256"},{"internalType":"bool","name":"allowSelfServeCompletion","type":"bool"},{"internalType":"address","name":"questValidator","type":"address"}],"name":"manageQuestValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nextQuestId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"questId","type":"uint256"},{"internalType":"address","name":"questContibutor","type":"address"}],"name":"questContributors","outputs":[{"internalType":"bool","name":"isContributor","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"questId","type":"uint256"}],"name":"quests","outputs":[{"components":[{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"string","name":"title","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"uint64","name":"experiencePoints","type":"uint64"},{"internalType":"enum IQuestTrackerEnums.QuestStatus","name":"status","type":"uint8"},{"internalType":"enum IQuestTrackerEnums.QuestType","name":"questType","type":"uint8"},{"internalType":"uint128","name":"maxCompletions","type":"uint128"},{"internalType":"uint64","name":"recursiveCooldown","type":"uint64"},{"internalType":"bool","name":"selfServeCompletion","type":"bool"},{"internalType":"address","name":"questValidator","type":"address"},{"internalType":"uint256[50]","name":"__gap","type":"uint256[50]"}],"internalType":"struct QuestTracker.Quest","name":"quest","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"questId","type":"uint256"}],"name":"recursiveQuestCompletions","outputs":[{"components":[{"internalType":"uint128","name":"totalCompletions","type":"uint128"},{"internalType":"uint128","name":"unallocatedCompletions","type":"uint128"},{"internalType":"uint128","name":"lastCompletionTimestamp","type":"uint128"},{"internalType":"uint256[50]","name":"__gap","type":"uint256[50]"}],"internalType":"struct QuestTracker.RecursiveQuestCompletions","name":"questCompletions","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"questId","type":"uint256"}],"name":"remainingLimitedQuestCompletions","outputs":[{"internalType":"uint256","name":"remainingCompletions","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"questId","type":"uint256"},{"internalType":"uint256","name":"updatedReward","type":"uint256"},{"internalType":"uint256","name":"updatedStartBlock","type":"uint256"},{"internalType":"uint256","name":"updatedEndBlock","type":"uint256"},{"internalType":"string","name":"updatedTitle","type":"string"},{"internalType":"string","name":"updatedDescription","type":"string"},{"internalType":"uint64","name":"updatedExperiencePoints","type":"uint64"},{"internalType":"enum IQuestTrackerEnums.QuestType","name":"updatedQuestType","type":"uint8"},{"internalType":"uint128","name":"updatedMaxCompletions","type":"uint128"},{"internalType":"uint64","name":"updatedRecursiveCooldown","type":"uint64"}],"name":"updateQuest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_questId","type":"uint256"},{"internalType":"address","name":"_contributor","type":"address"},{"internalType":"bool","name":"_isContributor","type":"bool"}],"name":"updateQuestContributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"questId","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"enum IQuestTrackerEnums.UserQuestStatus","name":"status","type":"uint8"}],"name":"updateUserQuestStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"userQuestProgress","outputs":[{"components":[{"internalType":"uint256","name":"numberOfCompletedQuests","type":"uint256"},{"internalType":"uint256","name":"lifetimePoints","type":"uint256"},{"internalType":"uint64","name":"lifetimeExperienceEarned","type":"uint64"},{"internalType":"uint64","name":"currentLevelExperiencePoints","type":"uint64"},{"internalType":"uint64","name":"currentLevel","type":"uint64"},{"internalType":"uint256[50]","name":"__gap","type":"uint256[50]"}],"internalType":"struct QuestTracker.UserData","name":"userData","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"questId","type":"uint256"}],"name":"userQuestStatus","outputs":[{"internalType":"enum IQuestTrackerEnums.UserQuestStatus","name":"status","type":"uint8"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50614483806100206000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806379ba509711610104578063d638c983116100a2578063e0b6bf4311610071578063e0b6bf43146104cf578063e1d93637146104ef578063e8f2ebf91461051d578063fc403b7a1461053057600080fd5b8063d638c98314610458578063d7c7a41f14610461578063e02140f914610474578063e085f980146104af57600080fd5b806394b2fbae116100de57806394b2fbae146103f1578063ab9a73f514610412578063c4d66de814610432578063c995e5be1461044557600080fd5b806379ba5097146103b657806379de70bf146103be5780638da5cb5b146103d157600080fd5b80633dd03042116101715780634fd9d1e01161014b5780634fd9d1e01461032257806353a47bb71461034557806353d68ab91461038a578063638b27cb146103a357600080fd5b80633dd03042146102e957806341f31ee3146102fc5780634cf9464b1461030f57600080fd5b80631627540c116101ad5780631627540c1461024457806321923bde14610257578063227f56df14610283578063300aa6b9146102d657600080fd5b80630d77d2df146101d45780631030957e14610212578063158ef93e14610227575b600080fd5b6101ff6101e2366004613651565b603b60209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b61022561022036600461368a565b610543565b005b603d546102349060ff1681565b6040519015158152602001610209565b6102256102523660046136c6565b6106f6565b61026a6102653660046136c6565b6107c1565b60405167ffffffffffffffff9091168152602001610209565b6102b56102913660046136e1565b6036602052600090815260409020546fffffffffffffffffffffffffffffffff1681565b6040516fffffffffffffffffffffffffffffffff9091168152602001610209565b6102256102e4366004613812565b610865565b6101ff6102f73660046136e1565b610a5b565b61022561030a366004613925565b610b21565b61026a61031d3660046139b1565b610dd3565b6102346103303660046136c6565b60026020526000908152604090205460ff1681565b6001546103659073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610209565b603d5461026a90610100900467ffffffffffffffff1681565b6102256103b1366004613a89565b610e6e565b610225611644565b6102256103cc366004613b58565b611720565b6000546103659073ffffffffffffffffffffffffffffffffffffffff1681565b603d5461026a906901000000000000000000900467ffffffffffffffff1681565b610425610420366004613651565b611a20565b6040516102099190613bd6565b6102256104403660046136c6565b611ae7565b610225610453366004613c38565b611b8f565b6101ff603c5481565b61022561046f366004613c6b565b611df0565b6104a2610482366004613651565b603960209081526000928352604080842090915290825290205460ff1681565b6040516102099190613ce1565b6104c26104bd3660046136e1565b611f55565b6040516102099190613d6c565b6104e26104dd3660046136c6565b612206565b6040516102099190613ec4565b6102346104fd366004613f1d565b600360209081526000928352604080842090915290825290205460ff1681565b61022561052b366004613f49565b6122cf565b61022561053e366004614034565b6127e7565b61054c8361292d565b603c548310610587576040517f8150a44b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260396020908152604080832086845290915290205460ff1660028111156105cc576105cc613c9e565b8160028111156105de576105de613c9e565b1115801561061f575060026000848152603760205260409020600501546901000000000000000000900460ff16600381111561061c5761061c613c9e565b14155b156106975773ffffffffffffffffffffffffffffffffffffffff82166000908152603960209081526040808320868452909152908190205490517fad4955fe00000000000000000000000000000000000000000000000000000000815261068e9160ff1690839060040161405e565b60405180910390fd5b6106a28383836129a1565b828273ffffffffffffffffffffffffffffffffffffffff167fd9e580fcfd14507572b3d361f3d417659f0904750daa571d71973973f9d70f22836040516106e99190613ce1565b60405180910390a3505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610747576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020015b60405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff81166000908152603a6020526040812060020154700100000000000000000000000000000000900467ffffffffffffffff16810361081657506001919050565b5073ffffffffffffffffffffffffffffffffffffffff166000908152603a6020526040902060020154700100000000000000000000000000000000900467ffffffffffffffff1690565b919050565b61086e8361292d565b603c5483106108a9576040517f8150a44b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015610a5557603960008483815181106108cb576108cb614079565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812087825290925290205460ff16600281111561091d5761091d613c9e565b82600281111561092f5761092f613c9e565b116109c1576039600084838151811061094a5761094a614079565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260409081016000908120878252909252908190205490517fad4955fe00000000000000000000000000000000000000000000000000000000815261068e9160ff1690849060040161405e565b6109e5848483815181106109d7576109d7614079565b6020026020010151846129a1565b838382815181106109f8576109f8614079565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fd9e580fcfd14507572b3d361f3d417659f0904750daa571d71973973f9d70f2284604051610a459190613ce1565b60405180910390a36001016108ac565b50505050565b600060036000838152603760205260409020600501546901000000000000000000900460ff166003811115610a9257610a92613c9e565b03610afa57600082815260366020908152604080832054603790925290912060050154610ae2916fffffffffffffffffffffffffffffffff908116916a01000000000000000000009004166140d7565b6fffffffffffffffffffffffffffffffff1692915050565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff919050565b610b2961312a565b8051835114610b64576040517fa24a13a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8351811015610a5557603c54848281518110610b8557610b85614079565b602002602001015110610bc4576040517f8150a44b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831660009081526039602052604081208551909190869084908110610c0057610c00614079565b60209081029190910181015182528101919091526040016000205460ff166002811115610c2f57610c2f613c9e565b828281518110610c4157610c41614079565b60200260200101516002811115610c5a57610c5a613c9e565b11610d0d5773ffffffffffffffffffffffffffffffffffffffff831660009081526039602052604081208551909190869084908110610c9b57610c9b614079565b6020026020010151815260200190815260200160002060009054906101000a900460ff16828281518110610cd157610cd1614079565b60200260200101516040517fad4955fe00000000000000000000000000000000000000000000000000000000815260040161068e92919061405e565b610d4a848281518110610d2257610d22614079565b602002602001015184848481518110610d3d57610d3d614079565b60200260200101516129a1565b838181518110610d5c57610d5c614079565b60200260200101518373ffffffffffffffffffffffffffffffffffffffff167fd9e580fcfd14507572b3d361f3d417659f0904750daa571d71973973f9d70f22848481518110610dae57610dae614079565b6020026020010151604051610dc39190613ce1565b60405180910390a3600101610b67565b60008167ffffffffffffffff16600003610e19576040517fd1459f7900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603d546000906901000000000000000000900467ffffffffffffffff16610e41600185614100565b610e4b9190614121565b603d54610e679190610100900467ffffffffffffffff1661414d565b9392505050565b610e7661312a565b603c548a10610eb1576040517f8150a44b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000603760008c8152602001908152602001600020604051806101a0016040529081600082015481526020016001820154815260200160028201548152602001600382018054610f009061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610f2c9061416e565b8015610f795780601f10610f4e57610100808354040283529160200191610f79565b820191906000526020600020905b815481529060010190602001808311610f5c57829003601f168201915b50505050508152602001600482018054610f929061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610fbe9061416e565b801561100b5780601f10610fe05761010080835404028352916020019161100b565b820191906000526020600020905b815481529060010190602001808311610fee57829003601f168201915b5050509183525050600582015467ffffffffffffffff8116602083015260409091019068010000000000000000900460ff16600381111561104e5761104e613c9e565b600381111561105f5761105f613c9e565b81526020016005820160099054906101000a900460ff16600381111561108757611087613c9e565b600381111561109857611098613c9e565b815260058201546a010000000000000000000090046fffffffffffffffffffffffffffffffff166020820152600682015467ffffffffffffffff811660408084019190915268010000000000000000820460ff1615156060840152690100000000000000000090910473ffffffffffffffffffffffffffffffffffffffff166080830152805161064081019182905260a09092019190600784019060329082845b815481526020019060010190808311611139575050505050815250509050896000146111655789611168565b80515b99508815611176578861117c565b80602001515b9850871561118a5787611190565b80604001515b975067ffffffffffffffff8516156111a857846111ae565b8060a001515b945086516000146111bf57866111c5565b80606001515b965085516000146111d657856111dc565b80608001515b955060008460038111156111f2576111f2613c9e565b146111fd5783611203565b8060e001515b9350600384600381111561121957611219613c9e565b146112275760009250611247565b6fffffffffffffffffffffffffffffffff83166112475780610100015192505b600284600381111561125b5761125b613c9e565b146112695760009150611281565b67ffffffffffffffff82166112815780610120015191505b878911156112bb576040517f4a90c82c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000894310156112cd575060016112e1565b884310156112dd575060026112e1565b5060035b6112e96134b6565b604051806101a001604052808d81526020018c81526020018b81526020018a81526020018981526020018867ffffffffffffffff16815260200183600381111561133557611335613c9e565b815260200187600381111561134c5761134c613c9e565b8152602001866fffffffffffffffffffffffffffffffff1681526020018567ffffffffffffffff1681526020018461014001511515815260200184610160015173ffffffffffffffffffffffffffffffffffffffff16815260200182815250603760008f815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030190816113f19190614212565b50608082015160048201906114069082614212565b5060a082015160058201805467ffffffffffffffff9092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000083168117825560c0850151927fffffffffffffffffffffffffffffffffffffffffffffff00000000000000000016176801000000000000000083600381111561148a5761148a613c9e565b021790555060e08201516005820180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1669010000000000000000008360038111156114d9576114d9613c9e565b02179055506101008201516005820180546fffffffffffffffffffffffffffffffff9092166a0100000000000000000000027fffffffffffff00000000000000000000000000000000ffffffffffffffffffff90921691909117905561012082015160068201805461014085015161016086015173ffffffffffffffffffffffffffffffffffffffff166901000000000000000000027fffffff0000000000000000000000000000000000000000ffffffffffffffffff91151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000000000000090931667ffffffffffffffff9095169490941791909117169190911790556101808201516115f390600783019060326134d5565b509050508c7ff9563eeed6ea72b1ce1b1a6f05ff561a9c1427041e7ff09402b5b9ad7575da898d8d8d8660405161162d949392919061432c565b60405180910390a250505050505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611695576040517fb1f6da5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080546001805473ffffffffffffffffffffffffffffffffffffffff8082167fffffffffffffffffffffffff0000000000000000000000000000000000000000808616821790965594909116909155604080519190921680825260208201939093527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91016107b6565b61172861312a565b8251825114611763576040517fa24a13a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805183511461179e576040517fa24a13a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015610a5557603c548482815181106117bf576117bf614079565b6020026020010151106117fe576040517f8150a44b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6039600084838151811061181457611814614079565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085838151811061186a5761186a614079565b60209081029190910181015182528101919091526040016000205460ff16600281111561189957611899613c9e565b8282815181106118ab576118ab614079565b602002602001015160028111156118c4576118c4613c9e565b1161193557603960008483815181106118df576118df614079565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858381518110610c9b57610c9b614079565b61197e84828151811061194a5761194a614079565b602002602001015184838151811061196457611964614079565b6020026020010151848481518110610d3d57610d3d614079565b83818151811061199057611990614079565b60200260200101518382815181106119aa576119aa614079565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fd9e580fcfd14507572b3d361f3d417659f0904750daa571d71973973f9d70f228484815181106119fb576119fb614079565b6020026020010151604051611a109190613ce1565b60405180910390a36001016117a1565b611a28613513565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603860209081526040808320858452825291829020825160808101845281546fffffffffffffffffffffffffffffffff80821683527001000000000000000000000000000000009091048116938201939093526001820154909216828401528251610640810193849052919290916060840191600284019060329082845b815481526020019060010190808311611ac25750505050508152505090505b92915050565b603d5460ff1615611b24576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603d80547fffffffffffffffffffffffffffffff00000000000000000000000000000000ff166932000000000000006400179055611b6181613175565b50603d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b611b9761312a565b603c548310611bd2576040517f8150a44b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152603760205260409020600681015460ff68010000000000000000909104161515831515148015611c305750600681015473ffffffffffffffffffffffffffffffffffffffff838116690100000000000000000090920416145b15611c67576040517f48cd4af400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b828015611c88575073ffffffffffffffffffffffffffffffffffffffff8216155b15611cbf576040517f33031b5500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006810180547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000008515150217905582611d2c576006810180547fffffff0000000000000000000000000000000000000000ffffffffffffffffff169055611d7b565b6006810180547fffffff0000000000000000000000000000000000000000ffffffffffffffffff16690100000000000000000073ffffffffffffffffffffffffffffffffffffffff8516021790555b600681015460405168010000000000000000820460ff1615158152690100000000000000000090910473ffffffffffffffffffffffffffffffffffffffff169085907fb5ccbdda01c52db2c7cc2477a4c2079e48ef79d2e2ba0c68ee49a4420430641d9060200160405180910390a350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611e41576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290205481151560ff909116151503611eb2576040517fd31fc68300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168515159081179091558151878152928301939093528101919091527f8f670544d20af5fd2c568b1c2f0e21971fb6e9e6cc303fe9fac7579bc983ad319060600160405180910390a1505050565b611f5d613541565b60376000838152602001908152602001600020604051806101a0016040529081600082015481526020016001820154815260200160028201548152602001600382018054611faa9061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054611fd69061416e565b80156120235780601f10611ff857610100808354040283529160200191612023565b820191906000526020600020905b81548152906001019060200180831161200657829003601f168201915b5050505050815260200160048201805461203c9061416e565b80601f01602080910402602001604051908101604052809291908181526020018280546120689061416e565b80156120b55780601f1061208a576101008083540402835291602001916120b5565b820191906000526020600020905b81548152906001019060200180831161209857829003601f168201915b5050509183525050600582015467ffffffffffffffff8116602083015260409091019068010000000000000000900460ff1660038111156120f8576120f8613c9e565b600381111561210957612109613c9e565b81526020016005820160099054906101000a900460ff16600381111561213157612131613c9e565b600381111561214257612142613c9e565b815260058201546a010000000000000000000090046fffffffffffffffffffffffffffffffff166020820152600682015467ffffffffffffffff811660408084019190915268010000000000000000820460ff1615156060840152690100000000000000000090910473ffffffffffffffffffffffffffffffffffffffff166080830152805161064081019182905260a09092019190600784019060329082845b8154815260200190600101908083116121e3575050505050815250509050919050565b61220e6135c4565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603a6020908152604091829020825160c08101845281548152600182015481840152600282015467ffffffffffffffff8082168387015268010000000000000000820481166060840152700100000000000000000000000000000000909104166080820152835161064081019485905260038301805482529194929360a0860193919291603291600487019085018083116121e3575050505050815250509050919050565b6122d761312a565b888a1115612311576040517f4a90c82c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008a43101561232357506001612337565b8943101561233357506002612337565b5060035b600086600381111561234b5761234b613c9e565b146123565785612359565b60015b9550600386600381111561236f5761236f613c9e565b1461237b57600061237d565b845b9450600286600381111561239357612393613c9e565b1461239f5760006123a1565b835b9350826123af5760006123b1565b815b91508280156123d4575073ffffffffffffffffffffffffffffffffffffffff8216155b1561240b576040517f33031b5500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124136134b6565b604051806101a001604052808e81526020018d81526020018c81526020018b81526020018a81526020018967ffffffffffffffff16815260200183600381111561245f5761245f613c9e565b815260200188600381111561247657612476613c9e565b8152602001876fffffffffffffffffffffffffffffffff1681526020018667ffffffffffffffff16815260200185151581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018281525060376000603c54815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030190816125139190614212565b50608082015160048201906125289082614212565b5060a082015160058201805467ffffffffffffffff9092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000083168117825560c0850151927fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000001617680100000000000000008360038111156125ac576125ac613c9e565b021790555060e08201516005820180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1669010000000000000000008360038111156125fb576125fb613c9e565b02179055506101008201516005820180546fffffffffffffffffffffffffffffffff9092166a0100000000000000000000027fffffffffffff00000000000000000000000000000000ffffffffffffffffffff90921691909117905561012082015160068201805461014085015161016086015173ffffffffffffffffffffffffffffffffffffffff166901000000000000000000027fffffff0000000000000000000000000000000000000000ffffffffffffffffff91151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000000000000090931667ffffffffffffffff90951694909417919091171691909117905561018082015161271590600783019060326134d5565b5050603c80549150600061272883614359565b91905055506001603c5461273c9190614391565b604080518f8152602081018f90529081018d90527f564d54b0c338901d75d2e732afcb7cb2aeba7be8b25fb42fdaaf3621239dc9b29060600160405180910390a28273ffffffffffffffffffffffffffffffffffffffff166001603c546127a39190614391565b60405186151581527fb5ccbdda01c52db2c7cc2477a4c2079e48ef79d2e2ba0c68ee49a4420430641d9060200160405180910390a350505050505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612838576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205481151560ff90911615150361289f576040517fd31fc68300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526002602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168515159081179091558251938452908301527f1b6e6916bd76fb0e62ff02acf466a38852d02426c13ba96e69803693ac627d58910160405180910390a15050565b3360009081526002602052604090205460ff161580156129675750600081815260036020908152604080832033845290915290205460ff16155b1561299e576040517f0e20c7ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b6000838152603760209081526040808320600581015473ffffffffffffffffffffffffffffffffffffffff871685526039845282852088865290935292205460ff6901000000000000000000909204821691166003826003811115612a0857612a08613c9e565b03612a9c5760058301546000878152603660205260409020546fffffffffffffffffffffffffffffffff6a01000000000000000000009092048216911610801590612a6557506001816002811115612a6257612a62613c9e565b14155b15612a9c576040517fdf11444700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002826003811115612ab057612ab0613c9e565b03612c0057600683015473ffffffffffffffffffffffffffffffffffffffff861660009081526038602090815260408083208a845290915290206001015467ffffffffffffffff909116904290612b1a9083906fffffffffffffffffffffffffffffffff166143a4565b1115612b52576040517f9a4615fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002856002811115612b6657612b66613c9e565b148015612bc7575073ffffffffffffffffffffffffffffffffffffffff861660009081526038602090815260408083208a845290915290205470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16155b15612bfe576040517fbfef4a7200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b6000816002811115612c1457612c14613c9e565b1480612c4d57506002826003811115612c2f57612c2f613c9e565b148015612c4d57506001846002811115612c4b57612c4b613c9e565b145b15612fa45773ffffffffffffffffffffffffffffffffffffffff85166000818152603b60209081526040808320603a808452828520805486529184529184208b9055938352905281549190612ca183614359565b90915550506005830154612cc090869067ffffffffffffffff1661320c565b6002826003811115612cd457612cd4613c9e565b03612e365773ffffffffffffffffffffffffffffffffffffffff85166000908152603860209081526040808320898452909152812080546fffffffffffffffffffffffffffffffff1691612d27836143b7565b82546101009290920a6fffffffffffffffffffffffffffffffff81810219909316918316021790915573ffffffffffffffffffffffffffffffffffffffff871660009081526038602090815260408083208b845290915290208054700100000000000000000000000000000000900490911691506010612da6836143b7565b82546101009290920a6fffffffffffffffffffffffffffffffff81810219909316918316021790915573ffffffffffffffffffffffffffffffffffffffff871660009081526038602090815260408083208b8452909152902060010180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000164290921691909117905550612fa4565b6003826003811115612e4a57612e4a613c9e565b03612fa457600086815260366020526040812080546fffffffffffffffffffffffffffffffff1691612e7b836143b7565b91906101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505060006002811115612ec557612ec5613c9e565b816002811115612ed757612ed7613c9e565b148015612f1a575060058301546000878152603660205260409020546fffffffffffffffffffffffffffffffff6a01000000000000000000009092048216911610155b15612fa4576005830180547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff166803000000000000000017905543600284018190558354600185015460405189937ff9563eeed6ea72b1ce1b1a6f05ff561a9c1427041e7ff09402b5b9ad7575da8993612f9b93909290919060039061432c565b60405180910390a25b6002846002811115612fb857612fb8613c9e565b036130b257825473ffffffffffffffffffffffffffffffffffffffff86166000908152603a602052604081206001018054909190612ff79084906143a4565b909155506002905082600381111561301157613011613c9e565b036130b25773ffffffffffffffffffffffffffffffffffffffff851660009081526038602090815260408083208984529091529020805470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690601061307a836143e6565b91906101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550505b73ffffffffffffffffffffffffffffffffffffffff85166000908152603960209081526040808320898452909152902080548591907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183600281111561311d5761311d613c9e565b0217905550505050505050565b3360009081526002602052604090205460ff16613173576040517f6b697ed100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60005473ffffffffffffffffffffffffffffffffffffffff16156131c5576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603a602052604081206002810180549192849261325090849067ffffffffffffffff1661414d565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550818160020160088282829054906101000a900467ffffffffffffffff1661329d919061414d565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055508060020160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1660000361332b576002810180547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000001790555b600281015460009061335a90700100000000000000000000000000000000900467ffffffffffffffff16610dd3565b90505b600282015467ffffffffffffffff808316680100000000000000009092041610610a5557808260020160088282829054906101000a900467ffffffffffffffff166133a89190614100565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555081600201601081819054906101000a900467ffffffffffffffff16809291906133f690614430565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550508160020160109054906101000a900467ffffffffffffffff1667ffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fdccdbd00266b209f095bfa9fd02e02206fc2f4fa4cce243bb3218bd0ec04cfa460405160405180910390a360028201546134af90700100000000000000000000000000000000900467ffffffffffffffff16610dd3565b905061335d565b6040518061064001604052806032906020820280368337509192915050565b8260328101928215613503579160200282015b828111156135035782518255916020019190600101906134e8565b5061350f929150613618565b5090565b60408051608081018252600080825260208201819052918101919091526060810161353c6134b6565b905290565b604051806101a001604052806000815260200160008152602001600081526020016060815260200160608152602001600067ffffffffffffffff1681526020016000600381111561359457613594613c9e565b8152602001600081526000602082018190526040820181905260608201819052608082015260a00161353c6134b6565b6040518060c001604052806000815260200160008152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff16815260200161353c6134b6565b5b8082111561350f5760008155600101613619565b803573ffffffffffffffffffffffffffffffffffffffff8116811461086057600080fd5b6000806040838503121561366457600080fd5b61366d8361362d565b946020939093013593505050565b80356003811061086057600080fd5b60008060006060848603121561369f57600080fd5b833592506136af6020850161362d565b91506136bd6040850161367b565b90509250925092565b6000602082840312156136d857600080fd5b610e678261362d565b6000602082840312156136f357600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613770576137706136fa565b604052919050565b600067ffffffffffffffff821115613792576137926136fa565b5060051b60200190565b600082601f8301126137ad57600080fd5b813560206137c26137bd83613778565b613729565b8083825260208201915060208460051b8701019350868411156137e457600080fd5b602086015b84811015613807576137fa8161362d565b83529183019183016137e9565b509695505050505050565b60008060006060848603121561382757600080fd5b83359250602084013567ffffffffffffffff81111561384557600080fd5b6138518682870161379c565b9250506136bd6040850161367b565b600082601f83011261387157600080fd5b813560206138816137bd83613778565b8083825260208201915060208460051b8701019350868411156138a357600080fd5b602086015b8481101561380757803583529183019183016138a8565b600082601f8301126138d057600080fd5b813560206138e06137bd83613778565b8083825260208201915060208460051b87010193508684111561390257600080fd5b602086015b84811015613807576139188161367b565b8352918301918301613907565b60008060006060848603121561393a57600080fd5b833567ffffffffffffffff8082111561395257600080fd5b61395e87838801613860565b945061396c6020870161362d565b9350604086013591508082111561398257600080fd5b5061398f868287016138bf565b9150509250925092565b803567ffffffffffffffff8116811461086057600080fd5b6000602082840312156139c357600080fd5b610e6782613999565b600082601f8301126139dd57600080fd5b813567ffffffffffffffff8111156139f7576139f76136fa565b613a2860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613729565b818152846020838601011115613a3d57600080fd5b816020850160208301376000918101602001919091529392505050565b80356004811061086057600080fd5b80356fffffffffffffffffffffffffffffffff8116811461086057600080fd5b6000806000806000806000806000806101408b8d031215613aa957600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b013567ffffffffffffffff80821115613add57600080fd5b613ae98e838f016139cc565b975060a08d0135915080821115613aff57600080fd5b50613b0c8d828e016139cc565b955050613b1b60c08c01613999565b9350613b2960e08c01613a5a565b9250613b386101008c01613a69565b9150613b476101208c01613999565b90509295989b9194979a5092959850565b600080600060608486031215613b6d57600080fd5b833567ffffffffffffffff80821115613b8557600080fd5b613b9187838801613860565b94506020860135915080821115613ba757600080fd5b61396c8783880161379c565b8060005b6032811015610a55578151845260209384019390910190600101613bb7565b60006106a0820190506fffffffffffffffffffffffffffffffff808451168352806020850151166020840152806040850151166040840152506060830151613c216060840182613bb3565b5092915050565b8035801515811461086057600080fd5b600080600060608486031215613c4d57600080fd5b83359250613c5d60208501613c28565b91506136bd6040850161362d565b600080600060608486031215613c8057600080fd5b83359250613c906020850161362d565b91506136bd60408501613c28565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110613cdd57613cdd613c9e565b9052565b60208101611ae18284613ccd565b6000815180845260005b81811015613d1557602081850181015186830182015201613cf9565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6004811061299e5761299e613c9e565b613cdd81613d53565b60208152815160208201526020820151604082015260408201516060820152600060608301516107c06080840152613da86107e0840182613cef565b905060808401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160a0850152613de38282613cef565b91505060a0840151613e0160c085018267ffffffffffffffff169052565b5060c0840151613e1460e0850182613d63565b5060e0840151610100613e2981860183613d63565b8501519050610120613e4e858201836fffffffffffffffffffffffffffffffff169052565b8501519050610140613e6b8582018367ffffffffffffffff169052565b8501519050610160613e808582018315159052565b8501519050610180613ea98582018373ffffffffffffffffffffffffffffffffffffffff169052565b8501519050613ebc6101a0850182613bb3565b509392505050565b60006106e0820190508251825260208301516020830152604083015167ffffffffffffffff8082166040850152806060860151166060850152806080860151166080850152505060a0830151613c2160a0840182613bb3565b60008060408385031215613f3057600080fd5b82359150613f406020840161362d565b90509250929050565b60008060008060008060008060008060006101608c8e031215613f6b57600080fd5b8b359a5060208c0135995060408c0135985067ffffffffffffffff8060608e01351115613f9757600080fd5b613fa78e60608f01358f016139cc565b98508060808e01351115613fba57600080fd5b50613fcb8d60808e01358e016139cc565b9650613fd960a08d01613999565b9550613fe760c08d01613a5a565b9450613ff560e08d01613a69565b93506140046101008d01613999565b92506140136101208d01613c28565b91506140226101408d0161362d565b90509295989b509295989b9093969950565b6000806040838503121561404757600080fd5b6140508361362d565b9150613f4060208401613c28565b6040810161406c8285613ccd565b610e676020830184613ccd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6fffffffffffffffffffffffffffffffff828116828216039080821115613c2157613c216140a8565b67ffffffffffffffff828116828216039080821115613c2157613c216140a8565b67ffffffffffffffff818116838216028082169190828114614145576141456140a8565b505092915050565b67ffffffffffffffff818116838216019080821115613c2157613c216140a8565b600181811c9082168061418257607f821691505b6020821081036141bb577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561420d576000816000526020600020601f850160051c810160208610156141ea5750805b601f850160051c820191505b81811015614209578281556001016141f6565b5050505b505050565b815167ffffffffffffffff81111561422c5761422c6136fa565b6142408161423a845461416e565b846141c1565b602080601f831160018114614293576000841561425d5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614209565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156142e0578886015182559484019460019091019084016142c1565b508582101561431c57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b84815260208101849052604081018390526080810161434a83613d53565b82606083015295945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361438a5761438a6140a8565b5060010190565b81810381811115611ae157611ae16140a8565b80820180821115611ae157611ae16140a8565b60006fffffffffffffffffffffffffffffffff8083168181036143dc576143dc6140a8565b6001019392505050565b60006fffffffffffffffffffffffffffffffff821680614408576144086140a8565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b600067ffffffffffffffff8083168181036143dc576143dc6140a856fea2646970667358221220f28b197f57284abeab29b2d6ac208eed79793ca823387d5af7d1f44d35f8304564736f6c63430008170033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101cf5760003560e01c806379ba509711610104578063d638c983116100a2578063e0b6bf4311610071578063e0b6bf43146104cf578063e1d93637146104ef578063e8f2ebf91461051d578063fc403b7a1461053057600080fd5b8063d638c98314610458578063d7c7a41f14610461578063e02140f914610474578063e085f980146104af57600080fd5b806394b2fbae116100de57806394b2fbae146103f1578063ab9a73f514610412578063c4d66de814610432578063c995e5be1461044557600080fd5b806379ba5097146103b657806379de70bf146103be5780638da5cb5b146103d157600080fd5b80633dd03042116101715780634fd9d1e01161014b5780634fd9d1e01461032257806353a47bb71461034557806353d68ab91461038a578063638b27cb146103a357600080fd5b80633dd03042146102e957806341f31ee3146102fc5780634cf9464b1461030f57600080fd5b80631627540c116101ad5780631627540c1461024457806321923bde14610257578063227f56df14610283578063300aa6b9146102d657600080fd5b80630d77d2df146101d45780631030957e14610212578063158ef93e14610227575b600080fd5b6101ff6101e2366004613651565b603b60209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b61022561022036600461368a565b610543565b005b603d546102349060ff1681565b6040519015158152602001610209565b6102256102523660046136c6565b6106f6565b61026a6102653660046136c6565b6107c1565b60405167ffffffffffffffff9091168152602001610209565b6102b56102913660046136e1565b6036602052600090815260409020546fffffffffffffffffffffffffffffffff1681565b6040516fffffffffffffffffffffffffffffffff9091168152602001610209565b6102256102e4366004613812565b610865565b6101ff6102f73660046136e1565b610a5b565b61022561030a366004613925565b610b21565b61026a61031d3660046139b1565b610dd3565b6102346103303660046136c6565b60026020526000908152604090205460ff1681565b6001546103659073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610209565b603d5461026a90610100900467ffffffffffffffff1681565b6102256103b1366004613a89565b610e6e565b610225611644565b6102256103cc366004613b58565b611720565b6000546103659073ffffffffffffffffffffffffffffffffffffffff1681565b603d5461026a906901000000000000000000900467ffffffffffffffff1681565b610425610420366004613651565b611a20565b6040516102099190613bd6565b6102256104403660046136c6565b611ae7565b610225610453366004613c38565b611b8f565b6101ff603c5481565b61022561046f366004613c6b565b611df0565b6104a2610482366004613651565b603960209081526000928352604080842090915290825290205460ff1681565b6040516102099190613ce1565b6104c26104bd3660046136e1565b611f55565b6040516102099190613d6c565b6104e26104dd3660046136c6565b612206565b6040516102099190613ec4565b6102346104fd366004613f1d565b600360209081526000928352604080842090915290825290205460ff1681565b61022561052b366004613f49565b6122cf565b61022561053e366004614034565b6127e7565b61054c8361292d565b603c548310610587576040517f8150a44b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260396020908152604080832086845290915290205460ff1660028111156105cc576105cc613c9e565b8160028111156105de576105de613c9e565b1115801561061f575060026000848152603760205260409020600501546901000000000000000000900460ff16600381111561061c5761061c613c9e565b14155b156106975773ffffffffffffffffffffffffffffffffffffffff82166000908152603960209081526040808320868452909152908190205490517fad4955fe00000000000000000000000000000000000000000000000000000000815261068e9160ff1690839060040161405e565b60405180910390fd5b6106a28383836129a1565b828273ffffffffffffffffffffffffffffffffffffffff167fd9e580fcfd14507572b3d361f3d417659f0904750daa571d71973973f9d70f22836040516106e99190613ce1565b60405180910390a3505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610747576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020015b60405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff81166000908152603a6020526040812060020154700100000000000000000000000000000000900467ffffffffffffffff16810361081657506001919050565b5073ffffffffffffffffffffffffffffffffffffffff166000908152603a6020526040902060020154700100000000000000000000000000000000900467ffffffffffffffff1690565b919050565b61086e8361292d565b603c5483106108a9576040517f8150a44b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015610a5557603960008483815181106108cb576108cb614079565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812087825290925290205460ff16600281111561091d5761091d613c9e565b82600281111561092f5761092f613c9e565b116109c1576039600084838151811061094a5761094a614079565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260409081016000908120878252909252908190205490517fad4955fe00000000000000000000000000000000000000000000000000000000815261068e9160ff1690849060040161405e565b6109e5848483815181106109d7576109d7614079565b6020026020010151846129a1565b838382815181106109f8576109f8614079565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fd9e580fcfd14507572b3d361f3d417659f0904750daa571d71973973f9d70f2284604051610a459190613ce1565b60405180910390a36001016108ac565b50505050565b600060036000838152603760205260409020600501546901000000000000000000900460ff166003811115610a9257610a92613c9e565b03610afa57600082815260366020908152604080832054603790925290912060050154610ae2916fffffffffffffffffffffffffffffffff908116916a01000000000000000000009004166140d7565b6fffffffffffffffffffffffffffffffff1692915050565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff919050565b610b2961312a565b8051835114610b64576040517fa24a13a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8351811015610a5557603c54848281518110610b8557610b85614079565b602002602001015110610bc4576040517f8150a44b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff831660009081526039602052604081208551909190869084908110610c0057610c00614079565b60209081029190910181015182528101919091526040016000205460ff166002811115610c2f57610c2f613c9e565b828281518110610c4157610c41614079565b60200260200101516002811115610c5a57610c5a613c9e565b11610d0d5773ffffffffffffffffffffffffffffffffffffffff831660009081526039602052604081208551909190869084908110610c9b57610c9b614079565b6020026020010151815260200190815260200160002060009054906101000a900460ff16828281518110610cd157610cd1614079565b60200260200101516040517fad4955fe00000000000000000000000000000000000000000000000000000000815260040161068e92919061405e565b610d4a848281518110610d2257610d22614079565b602002602001015184848481518110610d3d57610d3d614079565b60200260200101516129a1565b838181518110610d5c57610d5c614079565b60200260200101518373ffffffffffffffffffffffffffffffffffffffff167fd9e580fcfd14507572b3d361f3d417659f0904750daa571d71973973f9d70f22848481518110610dae57610dae614079565b6020026020010151604051610dc39190613ce1565b60405180910390a3600101610b67565b60008167ffffffffffffffff16600003610e19576040517fd1459f7900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603d546000906901000000000000000000900467ffffffffffffffff16610e41600185614100565b610e4b9190614121565b603d54610e679190610100900467ffffffffffffffff1661414d565b9392505050565b610e7661312a565b603c548a10610eb1576040517f8150a44b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000603760008c8152602001908152602001600020604051806101a0016040529081600082015481526020016001820154815260200160028201548152602001600382018054610f009061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610f2c9061416e565b8015610f795780601f10610f4e57610100808354040283529160200191610f79565b820191906000526020600020905b815481529060010190602001808311610f5c57829003601f168201915b50505050508152602001600482018054610f929061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054610fbe9061416e565b801561100b5780601f10610fe05761010080835404028352916020019161100b565b820191906000526020600020905b815481529060010190602001808311610fee57829003601f168201915b5050509183525050600582015467ffffffffffffffff8116602083015260409091019068010000000000000000900460ff16600381111561104e5761104e613c9e565b600381111561105f5761105f613c9e565b81526020016005820160099054906101000a900460ff16600381111561108757611087613c9e565b600381111561109857611098613c9e565b815260058201546a010000000000000000000090046fffffffffffffffffffffffffffffffff166020820152600682015467ffffffffffffffff811660408084019190915268010000000000000000820460ff1615156060840152690100000000000000000090910473ffffffffffffffffffffffffffffffffffffffff166080830152805161064081019182905260a09092019190600784019060329082845b815481526020019060010190808311611139575050505050815250509050896000146111655789611168565b80515b99508815611176578861117c565b80602001515b9850871561118a5787611190565b80604001515b975067ffffffffffffffff8516156111a857846111ae565b8060a001515b945086516000146111bf57866111c5565b80606001515b965085516000146111d657856111dc565b80608001515b955060008460038111156111f2576111f2613c9e565b146111fd5783611203565b8060e001515b9350600384600381111561121957611219613c9e565b146112275760009250611247565b6fffffffffffffffffffffffffffffffff83166112475780610100015192505b600284600381111561125b5761125b613c9e565b146112695760009150611281565b67ffffffffffffffff82166112815780610120015191505b878911156112bb576040517f4a90c82c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000894310156112cd575060016112e1565b884310156112dd575060026112e1565b5060035b6112e96134b6565b604051806101a001604052808d81526020018c81526020018b81526020018a81526020018981526020018867ffffffffffffffff16815260200183600381111561133557611335613c9e565b815260200187600381111561134c5761134c613c9e565b8152602001866fffffffffffffffffffffffffffffffff1681526020018567ffffffffffffffff1681526020018461014001511515815260200184610160015173ffffffffffffffffffffffffffffffffffffffff16815260200182815250603760008f815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030190816113f19190614212565b50608082015160048201906114069082614212565b5060a082015160058201805467ffffffffffffffff9092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000083168117825560c0850151927fffffffffffffffffffffffffffffffffffffffffffffff00000000000000000016176801000000000000000083600381111561148a5761148a613c9e565b021790555060e08201516005820180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1669010000000000000000008360038111156114d9576114d9613c9e565b02179055506101008201516005820180546fffffffffffffffffffffffffffffffff9092166a0100000000000000000000027fffffffffffff00000000000000000000000000000000ffffffffffffffffffff90921691909117905561012082015160068201805461014085015161016086015173ffffffffffffffffffffffffffffffffffffffff166901000000000000000000027fffffff0000000000000000000000000000000000000000ffffffffffffffffff91151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000000000000090931667ffffffffffffffff9095169490941791909117169190911790556101808201516115f390600783019060326134d5565b509050508c7ff9563eeed6ea72b1ce1b1a6f05ff561a9c1427041e7ff09402b5b9ad7575da898d8d8d8660405161162d949392919061432c565b60405180910390a250505050505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611695576040517fb1f6da5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080546001805473ffffffffffffffffffffffffffffffffffffffff8082167fffffffffffffffffffffffff0000000000000000000000000000000000000000808616821790965594909116909155604080519190921680825260208201939093527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91016107b6565b61172861312a565b8251825114611763576040517fa24a13a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805183511461179e576040517fa24a13a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015610a5557603c548482815181106117bf576117bf614079565b6020026020010151106117fe576040517f8150a44b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6039600084838151811061181457611814614079565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600085838151811061186a5761186a614079565b60209081029190910181015182528101919091526040016000205460ff16600281111561189957611899613c9e565b8282815181106118ab576118ab614079565b602002602001015160028111156118c4576118c4613c9e565b1161193557603960008483815181106118df576118df614079565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000858381518110610c9b57610c9b614079565b61197e84828151811061194a5761194a614079565b602002602001015184838151811061196457611964614079565b6020026020010151848481518110610d3d57610d3d614079565b83818151811061199057611990614079565b60200260200101518382815181106119aa576119aa614079565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fd9e580fcfd14507572b3d361f3d417659f0904750daa571d71973973f9d70f228484815181106119fb576119fb614079565b6020026020010151604051611a109190613ce1565b60405180910390a36001016117a1565b611a28613513565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603860209081526040808320858452825291829020825160808101845281546fffffffffffffffffffffffffffffffff80821683527001000000000000000000000000000000009091048116938201939093526001820154909216828401528251610640810193849052919290916060840191600284019060329082845b815481526020019060010190808311611ac25750505050508152505090505b92915050565b603d5460ff1615611b24576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b603d80547fffffffffffffffffffffffffffffff00000000000000000000000000000000ff166932000000000000006400179055611b6181613175565b50603d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b611b9761312a565b603c548310611bd2576040517f8150a44b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838152603760205260409020600681015460ff68010000000000000000909104161515831515148015611c305750600681015473ffffffffffffffffffffffffffffffffffffffff838116690100000000000000000090920416145b15611c67576040517f48cd4af400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b828015611c88575073ffffffffffffffffffffffffffffffffffffffff8216155b15611cbf576040517f33031b5500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006810180547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000008515150217905582611d2c576006810180547fffffff0000000000000000000000000000000000000000ffffffffffffffffff169055611d7b565b6006810180547fffffff0000000000000000000000000000000000000000ffffffffffffffffff16690100000000000000000073ffffffffffffffffffffffffffffffffffffffff8516021790555b600681015460405168010000000000000000820460ff1615158152690100000000000000000090910473ffffffffffffffffffffffffffffffffffffffff169085907fb5ccbdda01c52db2c7cc2477a4c2079e48ef79d2e2ba0c68ee49a4420430641d9060200160405180910390a350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611e41576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915290205481151560ff909116151503611eb2576040517fd31fc68300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600083815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168515159081179091558151878152928301939093528101919091527f8f670544d20af5fd2c568b1c2f0e21971fb6e9e6cc303fe9fac7579bc983ad319060600160405180910390a1505050565b611f5d613541565b60376000838152602001908152602001600020604051806101a0016040529081600082015481526020016001820154815260200160028201548152602001600382018054611faa9061416e565b80601f0160208091040260200160405190810160405280929190818152602001828054611fd69061416e565b80156120235780601f10611ff857610100808354040283529160200191612023565b820191906000526020600020905b81548152906001019060200180831161200657829003601f168201915b5050505050815260200160048201805461203c9061416e565b80601f01602080910402602001604051908101604052809291908181526020018280546120689061416e565b80156120b55780601f1061208a576101008083540402835291602001916120b5565b820191906000526020600020905b81548152906001019060200180831161209857829003601f168201915b5050509183525050600582015467ffffffffffffffff8116602083015260409091019068010000000000000000900460ff1660038111156120f8576120f8613c9e565b600381111561210957612109613c9e565b81526020016005820160099054906101000a900460ff16600381111561213157612131613c9e565b600381111561214257612142613c9e565b815260058201546a010000000000000000000090046fffffffffffffffffffffffffffffffff166020820152600682015467ffffffffffffffff811660408084019190915268010000000000000000820460ff1615156060840152690100000000000000000090910473ffffffffffffffffffffffffffffffffffffffff166080830152805161064081019182905260a09092019190600784019060329082845b8154815260200190600101908083116121e3575050505050815250509050919050565b61220e6135c4565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603a6020908152604091829020825160c08101845281548152600182015481840152600282015467ffffffffffffffff8082168387015268010000000000000000820481166060840152700100000000000000000000000000000000909104166080820152835161064081019485905260038301805482529194929360a0860193919291603291600487019085018083116121e3575050505050815250509050919050565b6122d761312a565b888a1115612311576040517f4a90c82c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008a43101561232357506001612337565b8943101561233357506002612337565b5060035b600086600381111561234b5761234b613c9e565b146123565785612359565b60015b9550600386600381111561236f5761236f613c9e565b1461237b57600061237d565b845b9450600286600381111561239357612393613c9e565b1461239f5760006123a1565b835b9350826123af5760006123b1565b815b91508280156123d4575073ffffffffffffffffffffffffffffffffffffffff8216155b1561240b576040517f33031b5500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124136134b6565b604051806101a001604052808e81526020018d81526020018c81526020018b81526020018a81526020018967ffffffffffffffff16815260200183600381111561245f5761245f613c9e565b815260200188600381111561247657612476613c9e565b8152602001876fffffffffffffffffffffffffffffffff1681526020018667ffffffffffffffff16815260200185151581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018281525060376000603c54815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030190816125139190614212565b50608082015160048201906125289082614212565b5060a082015160058201805467ffffffffffffffff9092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000083168117825560c0850151927fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000001617680100000000000000008360038111156125ac576125ac613c9e565b021790555060e08201516005820180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff1669010000000000000000008360038111156125fb576125fb613c9e565b02179055506101008201516005820180546fffffffffffffffffffffffffffffffff9092166a0100000000000000000000027fffffffffffff00000000000000000000000000000000ffffffffffffffffffff90921691909117905561012082015160068201805461014085015161016086015173ffffffffffffffffffffffffffffffffffffffff166901000000000000000000027fffffff0000000000000000000000000000000000000000ffffffffffffffffff91151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff00000000000000000090931667ffffffffffffffff90951694909417919091171691909117905561018082015161271590600783019060326134d5565b5050603c80549150600061272883614359565b91905055506001603c5461273c9190614391565b604080518f8152602081018f90529081018d90527f564d54b0c338901d75d2e732afcb7cb2aeba7be8b25fb42fdaaf3621239dc9b29060600160405180910390a28273ffffffffffffffffffffffffffffffffffffffff166001603c546127a39190614391565b60405186151581527fb5ccbdda01c52db2c7cc2477a4c2079e48ef79d2e2ba0c68ee49a4420430641d9060200160405180910390a350505050505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612838576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205481151560ff90911615150361289f576040517fd31fc68300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526002602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168515159081179091558251938452908301527f1b6e6916bd76fb0e62ff02acf466a38852d02426c13ba96e69803693ac627d58910160405180910390a15050565b3360009081526002602052604090205460ff161580156129675750600081815260036020908152604080832033845290915290205460ff16155b1561299e576040517f0e20c7ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b6000838152603760209081526040808320600581015473ffffffffffffffffffffffffffffffffffffffff871685526039845282852088865290935292205460ff6901000000000000000000909204821691166003826003811115612a0857612a08613c9e565b03612a9c5760058301546000878152603660205260409020546fffffffffffffffffffffffffffffffff6a01000000000000000000009092048216911610801590612a6557506001816002811115612a6257612a62613c9e565b14155b15612a9c576040517fdf11444700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002826003811115612ab057612ab0613c9e565b03612c0057600683015473ffffffffffffffffffffffffffffffffffffffff861660009081526038602090815260408083208a845290915290206001015467ffffffffffffffff909116904290612b1a9083906fffffffffffffffffffffffffffffffff166143a4565b1115612b52576040517f9a4615fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002856002811115612b6657612b66613c9e565b148015612bc7575073ffffffffffffffffffffffffffffffffffffffff861660009081526038602090815260408083208a845290915290205470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16155b15612bfe576040517fbfef4a7200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b6000816002811115612c1457612c14613c9e565b1480612c4d57506002826003811115612c2f57612c2f613c9e565b148015612c4d57506001846002811115612c4b57612c4b613c9e565b145b15612fa45773ffffffffffffffffffffffffffffffffffffffff85166000818152603b60209081526040808320603a808452828520805486529184529184208b9055938352905281549190612ca183614359565b90915550506005830154612cc090869067ffffffffffffffff1661320c565b6002826003811115612cd457612cd4613c9e565b03612e365773ffffffffffffffffffffffffffffffffffffffff85166000908152603860209081526040808320898452909152812080546fffffffffffffffffffffffffffffffff1691612d27836143b7565b82546101009290920a6fffffffffffffffffffffffffffffffff81810219909316918316021790915573ffffffffffffffffffffffffffffffffffffffff871660009081526038602090815260408083208b845290915290208054700100000000000000000000000000000000900490911691506010612da6836143b7565b82546101009290920a6fffffffffffffffffffffffffffffffff81810219909316918316021790915573ffffffffffffffffffffffffffffffffffffffff871660009081526038602090815260408083208b8452909152902060010180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000164290921691909117905550612fa4565b6003826003811115612e4a57612e4a613c9e565b03612fa457600086815260366020526040812080546fffffffffffffffffffffffffffffffff1691612e7b836143b7565b91906101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505060006002811115612ec557612ec5613c9e565b816002811115612ed757612ed7613c9e565b148015612f1a575060058301546000878152603660205260409020546fffffffffffffffffffffffffffffffff6a01000000000000000000009092048216911610155b15612fa4576005830180547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff166803000000000000000017905543600284018190558354600185015460405189937ff9563eeed6ea72b1ce1b1a6f05ff561a9c1427041e7ff09402b5b9ad7575da8993612f9b93909290919060039061432c565b60405180910390a25b6002846002811115612fb857612fb8613c9e565b036130b257825473ffffffffffffffffffffffffffffffffffffffff86166000908152603a602052604081206001018054909190612ff79084906143a4565b909155506002905082600381111561301157613011613c9e565b036130b25773ffffffffffffffffffffffffffffffffffffffff851660009081526038602090815260408083208984529091529020805470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690601061307a836143e6565b91906101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550505b73ffffffffffffffffffffffffffffffffffffffff85166000908152603960209081526040808320898452909152902080548591907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183600281111561311d5761311d613c9e565b0217905550505050505050565b3360009081526002602052604090205460ff16613173576040517f6b697ed100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60005473ffffffffffffffffffffffffffffffffffffffff16156131c5576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603a602052604081206002810180549192849261325090849067ffffffffffffffff1661414d565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550818160020160088282829054906101000a900467ffffffffffffffff1661329d919061414d565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055508060020160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1660000361332b576002810180547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000001790555b600281015460009061335a90700100000000000000000000000000000000900467ffffffffffffffff16610dd3565b90505b600282015467ffffffffffffffff808316680100000000000000009092041610610a5557808260020160088282829054906101000a900467ffffffffffffffff166133a89190614100565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555081600201601081819054906101000a900467ffffffffffffffff16809291906133f690614430565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550508160020160109054906101000a900467ffffffffffffffff1667ffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fdccdbd00266b209f095bfa9fd02e02206fc2f4fa4cce243bb3218bd0ec04cfa460405160405180910390a360028201546134af90700100000000000000000000000000000000900467ffffffffffffffff16610dd3565b905061335d565b6040518061064001604052806032906020820280368337509192915050565b8260328101928215613503579160200282015b828111156135035782518255916020019190600101906134e8565b5061350f929150613618565b5090565b60408051608081018252600080825260208201819052918101919091526060810161353c6134b6565b905290565b604051806101a001604052806000815260200160008152602001600081526020016060815260200160608152602001600067ffffffffffffffff1681526020016000600381111561359457613594613c9e565b8152602001600081526000602082018190526040820181905260608201819052608082015260a00161353c6134b6565b6040518060c001604052806000815260200160008152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff16815260200161353c6134b6565b5b8082111561350f5760008155600101613619565b803573ffffffffffffffffffffffffffffffffffffffff8116811461086057600080fd5b6000806040838503121561366457600080fd5b61366d8361362d565b946020939093013593505050565b80356003811061086057600080fd5b60008060006060848603121561369f57600080fd5b833592506136af6020850161362d565b91506136bd6040850161367b565b90509250925092565b6000602082840312156136d857600080fd5b610e678261362d565b6000602082840312156136f357600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613770576137706136fa565b604052919050565b600067ffffffffffffffff821115613792576137926136fa565b5060051b60200190565b600082601f8301126137ad57600080fd5b813560206137c26137bd83613778565b613729565b8083825260208201915060208460051b8701019350868411156137e457600080fd5b602086015b84811015613807576137fa8161362d565b83529183019183016137e9565b509695505050505050565b60008060006060848603121561382757600080fd5b83359250602084013567ffffffffffffffff81111561384557600080fd5b6138518682870161379c565b9250506136bd6040850161367b565b600082601f83011261387157600080fd5b813560206138816137bd83613778565b8083825260208201915060208460051b8701019350868411156138a357600080fd5b602086015b8481101561380757803583529183019183016138a8565b600082601f8301126138d057600080fd5b813560206138e06137bd83613778565b8083825260208201915060208460051b87010193508684111561390257600080fd5b602086015b84811015613807576139188161367b565b8352918301918301613907565b60008060006060848603121561393a57600080fd5b833567ffffffffffffffff8082111561395257600080fd5b61395e87838801613860565b945061396c6020870161362d565b9350604086013591508082111561398257600080fd5b5061398f868287016138bf565b9150509250925092565b803567ffffffffffffffff8116811461086057600080fd5b6000602082840312156139c357600080fd5b610e6782613999565b600082601f8301126139dd57600080fd5b813567ffffffffffffffff8111156139f7576139f76136fa565b613a2860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613729565b818152846020838601011115613a3d57600080fd5b816020850160208301376000918101602001919091529392505050565b80356004811061086057600080fd5b80356fffffffffffffffffffffffffffffffff8116811461086057600080fd5b6000806000806000806000806000806101408b8d031215613aa957600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b013567ffffffffffffffff80821115613add57600080fd5b613ae98e838f016139cc565b975060a08d0135915080821115613aff57600080fd5b50613b0c8d828e016139cc565b955050613b1b60c08c01613999565b9350613b2960e08c01613a5a565b9250613b386101008c01613a69565b9150613b476101208c01613999565b90509295989b9194979a5092959850565b600080600060608486031215613b6d57600080fd5b833567ffffffffffffffff80821115613b8557600080fd5b613b9187838801613860565b94506020860135915080821115613ba757600080fd5b61396c8783880161379c565b8060005b6032811015610a55578151845260209384019390910190600101613bb7565b60006106a0820190506fffffffffffffffffffffffffffffffff808451168352806020850151166020840152806040850151166040840152506060830151613c216060840182613bb3565b5092915050565b8035801515811461086057600080fd5b600080600060608486031215613c4d57600080fd5b83359250613c5d60208501613c28565b91506136bd6040850161362d565b600080600060608486031215613c8057600080fd5b83359250613c906020850161362d565b91506136bd60408501613c28565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110613cdd57613cdd613c9e565b9052565b60208101611ae18284613ccd565b6000815180845260005b81811015613d1557602081850181015186830182015201613cf9565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6004811061299e5761299e613c9e565b613cdd81613d53565b60208152815160208201526020820151604082015260408201516060820152600060608301516107c06080840152613da86107e0840182613cef565b905060808401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08483030160a0850152613de38282613cef565b91505060a0840151613e0160c085018267ffffffffffffffff169052565b5060c0840151613e1460e0850182613d63565b5060e0840151610100613e2981860183613d63565b8501519050610120613e4e858201836fffffffffffffffffffffffffffffffff169052565b8501519050610140613e6b8582018367ffffffffffffffff169052565b8501519050610160613e808582018315159052565b8501519050610180613ea98582018373ffffffffffffffffffffffffffffffffffffffff169052565b8501519050613ebc6101a0850182613bb3565b509392505050565b60006106e0820190508251825260208301516020830152604083015167ffffffffffffffff8082166040850152806060860151166060850152806080860151166080850152505060a0830151613c2160a0840182613bb3565b60008060408385031215613f3057600080fd5b82359150613f406020840161362d565b90509250929050565b60008060008060008060008060008060006101608c8e031215613f6b57600080fd5b8b359a5060208c0135995060408c0135985067ffffffffffffffff8060608e01351115613f9757600080fd5b613fa78e60608f01358f016139cc565b98508060808e01351115613fba57600080fd5b50613fcb8d60808e01358e016139cc565b9650613fd960a08d01613999565b9550613fe760c08d01613a5a565b9450613ff560e08d01613a69565b93506140046101008d01613999565b92506140136101208d01613c28565b91506140226101408d0161362d565b90509295989b509295989b9093969950565b6000806040838503121561404757600080fd5b6140508361362d565b9150613f4060208401613c28565b6040810161406c8285613ccd565b610e676020830184613ccd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6fffffffffffffffffffffffffffffffff828116828216039080821115613c2157613c216140a8565b67ffffffffffffffff828116828216039080821115613c2157613c216140a8565b67ffffffffffffffff818116838216028082169190828114614145576141456140a8565b505092915050565b67ffffffffffffffff818116838216019080821115613c2157613c216140a8565b600181811c9082168061418257607f821691505b6020821081036141bb577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561420d576000816000526020600020601f850160051c810160208610156141ea5750805b601f850160051c820191505b81811015614209578281556001016141f6565b5050505b505050565b815167ffffffffffffffff81111561422c5761422c6136fa565b6142408161423a845461416e565b846141c1565b602080601f831160018114614293576000841561425d5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614209565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156142e0578886015182559484019460019091019084016142c1565b508582101561431c57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b84815260208101849052604081018390526080810161434a83613d53565b82606083015295945050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361438a5761438a6140a8565b5060010190565b81810381811115611ae157611ae16140a8565b80820180821115611ae157611ae16140a8565b60006fffffffffffffffffffffffffffffffff8083168181036143dc576143dc6140a8565b6001019392505050565b60006fffffffffffffffffffffffffffffffff821680614408576144086140a8565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b600067ffffffffffffffff8083168181036143dc576143dc6140a856fea2646970667358221220f28b197f57284abeab29b2d6ac208eed79793ca823387d5af7d1f44d35f8304564736f6c63430008170033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in FRAX
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.