ETH Price: $3,624.08 (-1.84%)

Contract

0x13182b9b97d27c5b09C5809b93c31F745d54aC82
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Claim Treasure176577402023-07-09 17:50:23512 days ago1688925023IN
0x13182b9b...45d54aC82
0 ETH0.0027714517.07420171
Claim Treasure176561642023-07-09 12:31:23512 days ago1688905883IN
0x13182b9b...45d54aC82
0 ETH0.0022691214.48236542
Claim Treasure176561602023-07-09 12:30:35512 days ago1688905835IN
0x13182b9b...45d54aC82
0 ETH0.0036225113.96789936
Claim Treasure176561582023-07-09 12:30:11512 days ago1688905811IN
0x13182b9b...45d54aC82
0 ETH0.0022725113.28865032
Claim Treasure176553912023-07-09 9:54:35512 days ago1688896475IN
0x13182b9b...45d54aC82
0 ETH0.0022339414.01012548
Claim Treasure176498962023-07-08 15:20:35513 days ago1688829635IN
0x13182b9b...45d54aC82
0 ETH0.0088478933.61165125
Claim Treasure176477882023-07-08 8:13:47513 days ago1688804027IN
0x13182b9b...45d54aC82
0 ETH0.0051006419.66824124
Claim Treasure176477752023-07-08 8:11:11513 days ago1688803871IN
0x13182b9b...45d54aC82
0 ETH0.0037135820.36179944
Claim Treasure176466742023-07-08 4:28:11513 days ago1688790491IN
0x13182b9b...45d54aC82
0 ETH0.0025387515.37036285
Claim Treasure176466702023-07-08 4:27:23513 days ago1688790443IN
0x13182b9b...45d54aC82
0 ETH0.0019312313.75748976
Claim Treasure176414122023-07-07 10:44:35514 days ago1688726675IN
0x13182b9b...45d54aC82
0 ETH0.0029311320.18439539
Claim Treasure176412272023-07-07 10:06:59514 days ago1688724419IN
0x13182b9b...45d54aC82
0 ETH0.0031223919.94195594
Claim Treasure176374872023-07-06 21:30:47514 days ago1688679047IN
0x13182b9b...45d54aC82
0 ETH0.0052771136.33926001
Claim Treasure176361132023-07-06 16:53:23515 days ago1688662403IN
0x13182b9b...45d54aC82
0 ETH0.0043762924.77408651
Claim Treasure176357582023-07-06 15:41:35515 days ago1688658095IN
0x13182b9b...45d54aC82
0 ETH0.0059895332.14579933
Claim Treasure176341722023-07-06 10:19:47515 days ago1688638787IN
0x13182b9b...45d54aC82
0 ETH0.0043013422.86586138
Claim Treasure176308802023-07-05 23:13:47515 days ago1688598827IN
0x13182b9b...45d54aC82
0 ETH0.0070918844.47663064
Claim Treasure176304742023-07-05 21:52:23515 days ago1688593943IN
0x13182b9b...45d54aC82
0 ETH0.0079515950.78103
Claim Treasure176299492023-07-05 20:06:47516 days ago1688587607IN
0x13182b9b...45d54aC82
0 ETH0.0134061451.6921084
Claim Treasure176298782023-07-05 19:52:35516 days ago1688586755IN
0x13182b9b...45d54aC82
0 ETH0.0086281853.12465357
Claim Treasure176293812023-07-05 18:11:35516 days ago1688580695IN
0x13182b9b...45d54aC82
0 ETH0.0080200251.22588365
Claim Treasure176287942023-07-05 16:12:59516 days ago1688573579IN
0x13182b9b...45d54aC82
0 ETH0.0135592855.32890149
Claim Treasure176287892023-07-05 16:11:59516 days ago1688573519IN
0x13182b9b...45d54aC82
0 ETH0.009680359.63790556
Claim Treasure176287482023-07-05 16:03:47516 days ago1688573027IN
0x13182b9b...45d54aC82
0 ETH0.010106362.23017718
Claim Treasure176261862023-07-05 7:25:23516 days ago1688541923IN
0x13182b9b...45d54aC82
0 ETH0.0092206852.19805942
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PxTrainerAdventure

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 10 : PxTrainerAdventure.sol
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.16;

import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "./PxWeekManager.sol";
import "./IPxChainlinkManager.sol";

/// @notice Thrown when all treasures are already claimed
error AlreadyClaimed();
/// @notice Thrown when address is not a winner
error NotAWinner();
/// @notice Thrown when input is not as expected condition
error InvalidInput();
/// @notice Thrown when treasure index doesn't exist
error InvalidTreasureIndex();
/// @notice Thrown when no available treasures to be transferred to the winner
error InsufficientToken();
/// @notice Thrown when the input signature is invalid.
error InvalidSignature();

contract PxTrainerAdventure is PxWeekManager, ReentrancyGuard {
    /// @notice code number for ERC1155 token
    uint8 public constant ERC_1155_TYPE = 1;
    /// @notice code number for ERC721 token
    uint8 public constant ERC_721_TYPE = 2;

    /// @notice Wallet address that keeps all treasures
    address public vaultWalletAddress;

    /// @notice Variable to store Sponsored Trips treasure information such
    ///         as the collection address, token ID, amount, and token type
    Treasure public sponsoredTrip;
    /// @notice List of addresses who have won Sponsored Trips 
    /// @custom:key wallet address
    /// @custom:value 'true' means already owns Sponsored Trips
    mapping(address => bool) public sponsoredTripWinners;

    /// @notice Check whether both array input has the same length or not
    /// @param length1 first length of the array input
    /// @param length2 second length of the array input
    modifier validArrayLength(uint256 length1, uint256 length2) {
        if (length1 != length2) {
            revert InvalidLength();
        }
        _;
    }

    /// @notice Check treasure token type and token ID input
    /// @dev Only ERC1155 and ERC721 are supported
    /// @param _treasure Treasure information
    modifier validTreasure(Treasure memory _treasure) {
        if (_treasure.contractType != ERC_1155_TYPE && _treasure.contractType != ERC_721_TYPE) {
            revert InvalidInput();
        }
        if (
            (_treasure.contractType == ERC_1155_TYPE && _treasure.tokenIds.length > 0) ||
            (_treasure.contractType == ERC_721_TYPE && _treasure.tokenIds.length == 0)
        ) {
            revert InvalidInput();
        }
        _;
    }

    /// @notice Emits when a treasure is claimed
    /// @param weekNumber Week number when the treasure is claimed
    /// @param userWallet Wallet address who claims the treasure
    /// @param collectionAddress The contract address of the treasure
    /// @param tokenId The treasure token ID in its contract address
    /// @param tokenType The token type 
    event TreasureTransferred(uint256 weekNumber, address userWallet, address collectionAddress, uint256 tokenId, uint256 tokenType);

    /// @notice The contract constructor
    /// @dev The constructor parameters only used as input
    ///      from PxWeekManager contract
    ///        More https://docs.chain.link/docs/vrf/v2/subscription/supported-networks/#configurations
    /// @param _pxChainlinkContractAddress signature contract address
    constructor(address _pxChainlinkContractAddress) PxWeekManager() {
        pxChainlinkManagerContract = IPxChainlinkManager(_pxChainlinkContractAddress);
    }

    /// @notice Sets Chainlink manager contract address
    /// @dev Chainlink manager is used as signer and to interact with Chainlink
    /// @param _pxChainlinkContractAddress Chainlink manager contract address
    function setpxChainlinkManagerContractAddress(address _pxChainlinkContractAddress) external onlyOwner {
        pxChainlinkManagerContract = IPxChainlinkManager(_pxChainlinkContractAddress);
    }

    /// @notice Set address to become vault
    /// @param _walletAddress Wallet address that will be the vault
    function setVaultWalletAddress(address _walletAddress) external onlyOwner {
        vaultWalletAddress = _walletAddress;
    }

    /// @notice Adds treasure information
    /// @dev This method is used to add information about the treasure that exists
    ///      in the vault wallet address. Only admin can call this method
    /// @param _treasure Treasure information
    function addTreasures(Treasure memory _treasure) external onlyAdmin(msg.sender) validTreasure(_treasure) {
        totalTreasureCount++;
        _treasure.claimedToken = 0;
        treasures[totalTreasureCount] = _treasure;
    }

    /// @notice Update existing treasure information
    /// @dev Only admin can call this method
    /// @param _index Treasure index
    /// @param _treasure New treasure information
    function updateTreasure(uint256 _index, Treasure memory _treasure) external onlyAdmin(msg.sender) validTreasure(_treasure) {
        _treasure.claimedToken = 0;
        treasures[_index] = _treasure;
    }

    /// @notice Add Sponsored Trips treasure to the smart contract
    /// @dev Can only be called by administrators
    /// @param _treasure Sponsored Trips information according to Treasure struct
    function addSponsoredTripTreasure(Treasure memory _treasure) external onlyAdmin(msg.sender) {
        if (_treasure.claimedToken != 0 || _treasure.contractType != ERC_1155_TYPE || _treasure.tokenIds.length > 0) {
            revert InvalidInput();
        }
        sponsoredTrip = _treasure;
    }

    /// @notice claim function for the winner
    /// @dev Only winner of the week can call this method
    /// @param _weekNumber The week number to claim treasure
    /// @param _signature Signature from signer wallet
    function claimTreasure(uint256 _weekNumber, bytes calldata _signature) external noContracts nonReentrant {
        if (!(block.timestamp >= weekInfos[_weekNumber].claimStartTimeStamp && block.timestamp <= weekInfos[_weekNumber].endTimeStamp)) {
            revert InvalidClaimingPeriod();
        }
        bool isValidSigner = pxChainlinkManagerContract.isSignerVerifiedFromSignature(
            _weekNumber,
            weekInfos[_weekNumber].winners[msg.sender].claimed,
            msg.sender,
            _signature
        );

        if (!isValidSigner) {
            revert InvalidSignature();
        }

        if (weekInfos[_weekNumber].winners[msg.sender].claimLimit == 0) {
            revert NotAWinner();
        }
        if (weekInfos[_weekNumber].winners[msg.sender].claimed == weekInfos[_weekNumber].winners[msg.sender].claimLimit) {
            revert AlreadyClaimed();
        }
        if (weekInfos[_weekNumber].winners[msg.sender].claimed == 0) {
            primaryClaim(_weekNumber);
        } else {
            secondaryClaim(_weekNumber);
        }
    }

    /// @notice Method to claim the first treasure
    /// @dev This method is also used to claim Sponsor Trips if
    ///      the caller is selected as a sponsored trip winner
    /// @param _weekNumber The week number to claim treasure
    function primaryClaim(uint256 _weekNumber) internal {
        Week storage week = weekInfos[_weekNumber];
        if (week.tripWinnersMap[msg.sender]) {
            sponsoredTripWinners[msg.sender] = true;
            week.tripWinnersMap[msg.sender] = false;

            unchecked {
                week.winners[msg.sender].claimed++;
                week.availabletripsCount--;
                sponsoredTrip.claimedToken++;
            }
            transferToken(_weekNumber, sponsoredTrip);
        } else {
            uint256 randomNumber = getRandomNumber();
            uint256 random = randomNumber - ((randomNumber / week.remainingSupply) * week.remainingSupply) + 1;

            uint256 selectedIndex;
            uint16 sumOfTotalSupply;

            for (uint256 index = 1; index <= week.treasureCount; index = _uncheckedInc(index)) {
                if (week.distributions[index].totalSupply == 0) {
                    continue;
                }
                unchecked {
                    sumOfTotalSupply += week.distributions[index].totalSupply;
                }
                if (random <= sumOfTotalSupply) {
                    selectedIndex = index;
                    break;
                }
            }
            uint256 selectedTreasureIndex = week.distributions[selectedIndex].treasureIndex;
            week.winners[msg.sender].treasureTypeClaimed[treasures[selectedTreasureIndex].treasureType] = true;

            unchecked {
                week.distributions[selectedIndex].totalSupply--;
                week.winners[msg.sender].claimed++;
                week.remainingSupply--;
                treasures[selectedTreasureIndex].claimedToken++;
            }

            transferToken(_weekNumber, treasures[selectedTreasureIndex]);
        }
    }

    /// @notice Method to claim the next treasure
    /// @dev This method will give different treasures than the first
    ///      one if there are still other treasure option available
    /// @param _weekNumber The week number to claim treasure
    function secondaryClaim(uint256 _weekNumber) internal {
        Week storage week = weekInfos[_weekNumber];
        uint16 remaining;
        uint16 altRemaining;

        for (uint256 index = 1; index <= week.treasureCount; index = _uncheckedInc(index)) {
            uint256 treasureType = treasures[week.distributions[index].treasureIndex].treasureType;
            if (week.winners[msg.sender].treasureTypeClaimed[treasureType]) {
                unchecked {
                    altRemaining += week.distributions[index].totalSupply;
                }
            } else {
                unchecked {
                    remaining += week.distributions[index].totalSupply;
                }
            }
        }
        uint256 randomNumber = getRandomNumber();

        uint256 selectedIndex;
        uint256 sumOfTotalSupply;
        if (altRemaining == week.remainingSupply) {
            uint256 random = randomNumber - ((randomNumber / altRemaining) * altRemaining) + 1;
            for (uint256 index = 1; index <= week.treasureCount; index = _uncheckedInc(index)) {
                uint256 treasureType = treasures[week.distributions[index].treasureIndex].treasureType;
                if (week.distributions[index].totalSupply == 0 || !week.winners[msg.sender].treasureTypeClaimed[treasureType]) {
                    continue;
                }
                unchecked {
                    sumOfTotalSupply += week.distributions[index].totalSupply;
                }
                if (random <= sumOfTotalSupply) {
                    selectedIndex = index;
                    break;
                }
            }
        } else {
            uint256 random = randomNumber - ((randomNumber / remaining) * remaining) + 1;

            for (uint256 index = 1; index <= week.treasureCount; index = _uncheckedInc(index)) {
                uint256 treasureType = treasures[week.distributions[index].treasureIndex].treasureType;
                if (week.distributions[index].totalSupply == 0 || week.winners[msg.sender].treasureTypeClaimed[treasureType]) {
                    continue;
                }
                unchecked {
                    sumOfTotalSupply += week.distributions[index].totalSupply;
                }
                if (random <= sumOfTotalSupply) {
                    selectedIndex = index;
                    break;
                }
            }
        }

        uint256 selectedTreasureIndex = week.distributions[selectedIndex].treasureIndex;
        week.winners[msg.sender].treasureTypeClaimed[treasures[selectedTreasureIndex].treasureType] = true;
        unchecked {
            week.distributions[selectedIndex].totalSupply--;
            week.winners[msg.sender].claimed++;
            week.remainingSupply--;
            treasures[selectedTreasureIndex].claimedToken++;
        }

        transferToken(_weekNumber, treasures[selectedTreasureIndex]);
    }

    /// @notice Transfers token from vault to the method caller's wallet address
    /// @dev This method will be used in a public method and user who call the
    ///      method will get a token from vault wallet address
    /// @param _treasure Treasure to transfer
    function transferToken(uint256 _weekNumber, Treasure memory _treasure) internal {
        if (_treasure.contractType == ERC_1155_TYPE) {
            IERC1155 erc1155Contract = IERC1155(_treasure.collectionAddress);
            erc1155Contract.safeTransferFrom(vaultWalletAddress, msg.sender, _treasure.tokenId, 1, "");
            emit TreasureTransferred(_weekNumber, msg.sender, _treasure.collectionAddress, _treasure.tokenId, _treasure.contractType);
        }
        if (_treasure.contractType == ERC_721_TYPE) {
            IERC721 erc721Contract = IERC721(_treasure.collectionAddress);
            if (_treasure.tokenIds.length < _treasure.claimedToken) {
                revert InsufficientToken();
            }
            erc721Contract.transferFrom(vaultWalletAddress, msg.sender, _treasure.tokenIds[_treasure.claimedToken - 1]);
            emit TreasureTransferred(_weekNumber, msg.sender, _treasure.collectionAddress,_treasure.tokenIds[_treasure.claimedToken - 1] , _treasure.contractType);
        }

        
    }

    /// @notice Set treasure distributions for a week
    /// @dev Only admin can call this method
    /// @param _weekNumber The week number
    /// @param _treasureindexes The index of the treasure in 'treasures' mapping variable
    /// @param _treasureCounts Amount of treasure that will be available to claim during the week
    function setWeeklyTreasureDistribution(
        uint256 _weekNumber,
        uint8[] memory _treasureindexes,
        uint16[] memory _treasureCounts,
        uint8 _sponsoredTripsCount
    ) external onlyAdmin(msg.sender) validTreaureDistributionPeriod(_weekNumber) validArrayLength(_treasureindexes.length, _treasureCounts.length) {
        Week storage week = weekInfos[_weekNumber];
        week.sponsoredTripsCount = _sponsoredTripsCount;
        week.availabletripsCount = _sponsoredTripsCount;
        week.treasureCount = 0;
        for (uint256 index = 0; index < _treasureindexes.length; index = _uncheckedInc(index)) {
            if (_treasureindexes[index] == 0 || _treasureindexes[index] > totalTreasureCount) {
                revert InvalidTreasureIndex();
            }
            week.treasureCount++;
            week.distributions[week.treasureCount].treasureIndex = _treasureindexes[index];
            week.distributions[week.treasureCount].totalSupply = _treasureCounts[index];
            week.remainingSupply += _treasureCounts[index];
        }
    }

    /// @notice Set a list of winners for a particular week
    /// @param _weekNumber The current week number
    /// @param _winners List of wallet addresses that have been selected as winners
    /// @param _treasureCounts Amount of treasure that have been awarded to the corresponding winner
    function updateWeeklyWinners(
        uint256 _weekNumber,
        address[] memory _winners,
        uint8[] memory _treasureCounts
    ) external onlyModerator(msg.sender) validArrayLength(_winners.length, _treasureCounts.length) validWinnerUpdationPeriod(_weekNumber) {
        for (uint256 index = 0; index < weekInfos[_weekNumber].tripWinners.length; index++) {
            address tripWinner = weekInfos[_weekNumber].tripWinners[index];
            weekInfos[_weekNumber].tripWinnersMap[tripWinner] = false;
        }
        uint256 randomNumber = getRandomNumber();
        uint256 randomIndex = randomNumber - ((randomNumber / _treasureCounts.length) * _treasureCounts.length);
        uint256 counter = 0;
        uint256 tripWinnerCount = 0;
        uint256 treasureCount = 0;
        address[] memory tmpTripWinners = new address[](weekInfos[_weekNumber].sponsoredTripsCount);
        while (counter < _treasureCounts.length) {
            if (randomIndex == _treasureCounts.length) {
                randomIndex = 0;
            }
            if (
                !sponsoredTripWinners[_winners[randomIndex]] &&
                tripWinnerCount < weekInfos[_weekNumber].sponsoredTripsCount &&
                _treasureCounts[randomIndex] > 0
            ) {
                weekInfos[_weekNumber].tripWinnersMap[_winners[randomIndex]] = true;
                tmpTripWinners[tripWinnerCount] = _winners[randomIndex];
                tripWinnerCount++;
            }

            weekInfos[_weekNumber].winners[_winners[randomIndex]].claimLimit = _treasureCounts[randomIndex];
            treasureCount += _treasureCounts[randomIndex];
            unchecked {
                randomIndex++;
                counter++;
            }
        }
        if (treasureCount > weekInfos[_weekNumber].remainingSupply + weekInfos[_weekNumber].sponsoredTripsCount) {
            revert("Invalid Treasure Amount");
        }

        weekInfos[_weekNumber].tripWinners = tmpTripWinners;
        emit WeeklyWinnersSet(_weekNumber, tmpTripWinners);
    }

    /// @notice Add a list of wallet addresses that have won Sponsored Trip
    /// @param _previousWinners List of addresses that have won Sponsored Trip
    /// @param _flags 'true' means already won
    function setSponsoredTripWinnerMap(
        address[] memory _previousWinners,
        bool[] memory _flags
    ) external onlyAdmin(msg.sender) validArrayLength(_previousWinners.length, _flags.length) {
        for (uint256 index = 0; index < _flags.length; index = _uncheckedInc(index)) {
            sponsoredTripWinners[_previousWinners[index]] = _flags[index];
        }
    }
}

File 2 of 10 : IERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

File 3 of 10 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

File 4 of 10 : PxWeekManager.sol
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.16;

/// @title Pixelmon Trainer Adventure Smart Contract
/// @author LiquidX
/// @notice This smart contract provides configuration for the Trainer Adventure event on Pixelmon
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./IPxChainlinkManager.sol";
import "./PxUtils.sol";

/// @notice Thrown when end timestamp is less than or equal to start timestamp
error InvalidTimeStamp();
/// @notice Thrown when week number doesn't exist
error InvalidWeekNumber();
/// @notice Thrown when week duration is less than total period for updating treasure and set the winners
error InvalidDuration();
/// @notice Thrown when updating treasure is beyond the schedule
error InvalidUpdationPeriod();
/// @notice Thrown when claiming treasure is beyond the schedule
error InvalidClaimingPeriod();
/// @notice Thrown when address has no "Admin" role
error NotAdmin();
/// @notice Thrown when address has no "Moderator" role
error NotModerator();
/// @notice Thrown when length of both arrays are not equal
error InvalidLength();

contract PxWeekManager is Ownable, PxUtils {
    
    /// @notice Struct object for winner information
    /// @param claimLimit Maximum treasure that can be claimed by winner for a particular week
    /// @param claimed Number of treasure that has been claimed by winner for a particular week
    /// @param treasureTypeClaimed Type of treasure that has been claimed by a winner for a particular week
    struct Winner {
        uint8 claimLimit;
        uint8 claimed;
        mapping(uint256 => bool) treasureTypeClaimed;
    }

    /// @notice Struct object to store treasure information
    /// @dev If the treasure is ERC1155,tokenIds is an  empty array
    ///      if the treasure is ERC721,tokenId value is a dummy
    /// @param collectionAddress Contract address of the treasure
    /// @param tokenId ERC1155 Treasure token ID 
    /// @param tokenIds ERC721 Treasure token IDs
    /// @param claimedToken Amount of token that has been claimed
    /// @param contractType 1 for ERC1155, 2 for ERC721
    /// @param treasureType Similar IDs for the treasure.Treasure ID is used
    ///        to identify the treasure that claimed by winner and it's used to make
    ///        sure the winner will get different set of prizes.
    struct Treasure {
        address collectionAddress;
        uint256 tokenId;
        uint256[] tokenIds;
        uint256 claimedToken;
        uint8 contractType;
        uint8 treasureType;
    }

    /// @notice Struct object to store information about treasure that distributed within a week
    /// @param treasureIndex Index of the treasure in the smart contract
    /// @param totalSupply Total supply of the treasure within a week
    struct TreasureDistribution {
        uint8 treasureIndex;
        uint16 totalSupply;
    }

    /// @notice Struct object to store week information
    /// @param startTimeStamp Start timestamp of the week
    /// @param ticketDrawTimeStamp ticket draw timestamp 
    /// @param claimStartTimeStamp claiming start timestamp
    /// @param endTimeStamp End timestamp of a week
    /// @param remainingSupply The remaining treasure supply that hasn't been claimed during
    ///        the week. This supply is the sum of every treasure supply excluding Sponsored Trips
    /// @param treasureCount How many treasure option is available
    /// @param sponsoredTripsCount How many Sponsored Trips is available in a week
    /// @param availabletripsCount How many Sponsored Trips treasure that has not been claimed
    /// @param tripWinners Winners of Sponsored Trips
    /// @param tripWinnersMap Map that contains address of the Sponsored Trips winner.
    ///        Map is used to easily validate whether the address is a winner rather than
    ///        iterating every index in a list/array to find a winner
    /// @param distributions Map of treasure that is distributed during the week
    /// @param winners List of winner of the week
    struct Week {
        uint256 startTimeStamp;
        uint256 ticketDrawTimeStamp;
        uint256 claimStartTimeStamp;
        uint256 endTimeStamp;
        uint256 remainingSupply;
        uint8 treasureCount;
        uint8 sponsoredTripsCount;
        uint8 availabletripsCount;
        address[] tripWinners;
        mapping(address => bool) tripWinnersMap;
        mapping(uint256 => TreasureDistribution) distributions;
        mapping(address => Winner) winners;
    }

    /// @notice Struct object for week information
    /// @dev This struct is only used as return type for getWeekInfo method
    /// @param tripWinners Winner of Sponsored Trips
    struct WeekData {
        address[] tripWinners;
        uint256[] randomNumbers;
    }

    /// @notice Total treasure options
    uint256 public totalTreasureCount;

    /// @notice Variable to store treasure information such as the collection
    ///         address, token ID, amount, and token type
    /// @custom:key treasure ID
    /// @custom:value Treasure information
    mapping(uint256 => Treasure) public treasures;

    /// @notice Total week to claim treasure
    uint256 public totalWeek;
    /// @notice Collection of information for each week
    mapping(uint256 => Week) public weekInfos;

    /// @notice List of address that has "Admin" role, 'true' means it has the privilege
    mapping(address => bool) public adminWallets;
    /// @notice List of address that has "Moderator" role, 'true' means it has the privilege
    mapping(address => bool) public moderatorWallets;

    /// @dev Signature Contract
    IPxChainlinkManager public pxChainlinkManagerContract;

    /// @notice Check whether address has "Admin" role
    /// @param _walletAddress Valid ethereum address
    modifier onlyAdmin(address _walletAddress) {
        if (!adminWallets[_walletAddress]) {
            revert NotAdmin();
        }
        _;
    }

    /// @notice Check whether address has "Moderator" role
    /// @param _walletAddress Valid ethereum address
    modifier onlyModerator(address _walletAddress) {
        if (!moderatorWallets[_walletAddress]) {
            revert NotModerator();
        }
        _;
    }

    /// @notice Check whether block.timestamp is within the schedule
    ///         to set treasure distribution
    /// @param _weekNumber Number of the week
    modifier validTreaureDistributionPeriod(uint256 _weekNumber) {
        if (!(block.timestamp >= weekInfos[_weekNumber].startTimeStamp && block.timestamp < weekInfos[_weekNumber].ticketDrawTimeStamp)) {
            revert InvalidUpdationPeriod();
        }
        _;
    }

    /// @notice Check whether block.timestamp is beyond the schedule
    ///         to update winner merkle root and chainlink
    /// @param _weekNumber Number of the week
    modifier validWinnerUpdationPeriod(uint256 _weekNumber) {
        if (!(block.timestamp >= weekInfos[_weekNumber].ticketDrawTimeStamp && block.timestamp < weekInfos[_weekNumber].claimStartTimeStamp)) {
            revert InvalidUpdationPeriod();
        }
        _;
    }

    /// @notice Check whether the input week number is valid
    /// @param _weekNumber Number of the week
    modifier validWeekNumber(uint256 _weekNumber) {
        if (_weekNumber == 0 || _weekNumber > totalWeek) {
            revert InvalidWeekNumber();
        }
        _;
    }

    /// @notice Emit when winners of the week has been selected
    /// @param weekNumber The week number
    /// @param tripWinners The winner for Sponsored Trips treasure
    event WeeklyWinnersSet(uint256 weekNumber, address[] tripWinners);

    /// @notice Constructor function
    constructor() {}

    /// @notice Set "Admin" role for specific address, 'true' means it has privilege
    /// @dev Only owner can call this method
    /// @param _walletAddress The address that will be set as admin
    /// @param _flag 'true' means the address is an admin
    function setAdminWallet(address _walletAddress, bool _flag) external onlyOwner {
        adminWallets[_walletAddress] = _flag;
    }

    /// @notice Set "Moderator" role for specific address, 'true' means it has privilege
    /// @dev Only owner can call this method
    /// @param _walletAddress The address that will be set as moderator
    /// @param _flag 'true' means the address is a moderator
    function setModeratorWallet(address _walletAddress, bool _flag) external onlyOwner {
        moderatorWallets[_walletAddress] = _flag;
    }

    /// @notice Update the week information related with timestamp
    /// @param _weekNumber Number of the week
    /// @param _startTimeStamp The start time of the event
    /// @param _prizeUpdationDuration Duration to update the treasure distribution
    /// @param _winnerUpdationDuration Duration to update winner list 
    /// @param _weeklyDuration How long the event will be held within a week
    function updateWeeklyTimeStamp(
        uint256 _weekNumber,
        uint256 _startTimeStamp,
        uint256 _prizeUpdationDuration,
        uint256 _winnerUpdationDuration,
        uint256 _weeklyDuration
    ) external onlyAdmin(msg.sender) validWeekNumber(_weekNumber) {
        if (_weeklyDuration <= (_prizeUpdationDuration + _winnerUpdationDuration)) {
            revert InvalidDuration();
        }
        if (_weekNumber != 1 && _startTimeStamp <= weekInfos[_weekNumber - 1].endTimeStamp) {
            revert InvalidTimeStamp();
        }
        if (_weekNumber != totalWeek && _startTimeStamp + _weeklyDuration - 1 >= weekInfos[_weekNumber + 1].startTimeStamp) {
            revert InvalidTimeStamp();
        }

        weekInfos[_weekNumber].startTimeStamp = _startTimeStamp;
        weekInfos[_weekNumber].ticketDrawTimeStamp = _startTimeStamp + _prizeUpdationDuration;
        weekInfos[_weekNumber].claimStartTimeStamp = _startTimeStamp + _prizeUpdationDuration + _winnerUpdationDuration;
        weekInfos[_weekNumber].endTimeStamp = _startTimeStamp + _weeklyDuration - 1;
    }

    /// @notice Set the week information related with timestamp
    /// @param _numberOfWeeks How many weeks the event will be held
    /// @param _startTimeStamp The start time of the event
    /// @param _prizeUpdationDuration Duration to update the treasure distribution
    /// @param _winnerUpdationDuration Duration to update winner list i
    /// @param _weeklyDuration How long the event will be held within a week
    function setWeeklyTimeStamp(
        uint256 _numberOfWeeks,
        uint256 _startTimeStamp,
        uint256 _prizeUpdationDuration,
        uint256 _winnerUpdationDuration,
        uint256 _weeklyDuration
    ) external onlyAdmin(msg.sender) {
        if (_weeklyDuration <= (_prizeUpdationDuration + _winnerUpdationDuration)) {
            revert InvalidDuration();
        }
        for (uint256 index = 0; index < _numberOfWeeks; index = _uncheckedInc(index)) {
            totalWeek++;
            weekInfos[totalWeek].startTimeStamp = _startTimeStamp;
            weekInfos[totalWeek].ticketDrawTimeStamp = _startTimeStamp + _prizeUpdationDuration;
            weekInfos[totalWeek].claimStartTimeStamp = _startTimeStamp + _prizeUpdationDuration + _winnerUpdationDuration;
            weekInfos[totalWeek].endTimeStamp = _startTimeStamp + _weeklyDuration - 1;
            _startTimeStamp += _weeklyDuration;
        }
    }

    // @notice Generate random number from Chainlink
    /// @param _weekNumber Number of the week
    function generateChainLinkRandomNumbers(uint256 _weekNumber) external onlyModerator(msg.sender) validWinnerUpdationPeriod(_weekNumber) {
        pxChainlinkManagerContract.generateChainLinkRandomNumbers(_weekNumber);
    }

    /// @notice Get week informations for specific week
    /// @param _weekNumber The number of the week
    /// @return week Information for specific week
    function getWeekInfo(uint256 _weekNumber) external view returns (WeekData memory week) {
        week.tripWinners = weekInfos[_weekNumber].tripWinners;
        week.randomNumbers = pxChainlinkManagerContract.getWeeklyRandomNumbers(_weekNumber);
    }

    /// @notice Get claimed count for a winner for specific week
    /// @param _weekNumber The number of the week
    /// @param _walletAddress wallet address of the winner
    /// @return count claim count
    function getWeeklyClaimedCount(uint256 _weekNumber, address _walletAddress) external view returns (uint8 count) {
        return weekInfos[_weekNumber].winners[_walletAddress].claimed;
    }

    /// @notice Get treasure distribution for specific week
    /// @param _weekNumber The number of the week
    /// @return tmp distribution for specific week
    function getWeeklyDistributions(uint256 _weekNumber) external view returns (TreasureDistribution[] memory tmp) {
        TreasureDistribution[] memory distributions = new TreasureDistribution[](weekInfos[_weekNumber].treasureCount);
        for (uint256 index = 1; index <= weekInfos[_weekNumber].treasureCount; index++) {
            distributions[index - 1] = weekInfos[_weekNumber].distributions[index];
        }
        return distributions;
    }

    /// @notice Get all treasures information
    /// @return tmp all treasures information
    function getTreasures() external view returns (Treasure[] memory tmp) {
        Treasure[] memory allTreasures = new Treasure[](totalTreasureCount);
        for (uint256 index = 1; index <= totalTreasureCount; index++) {
            allTreasures[index - 1] = treasures[index];
        }
        return allTreasures;
    }
    
    /// @notice Get treasures information by index
    /// @param _index treasure index
    /// @return tmp particular treasure information
    function getTreasureById(uint256 _index) external view returns (Treasure memory tmp) {
        return treasures[_index];
    }
}

File 5 of 10 : IPxChainlinkManager.sol
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.16;

interface IPxChainlinkManager {
    /// @notice Recovers signer wallet from signature
    /// @dev View function for signature recovering
    /// @param weekNumber Week number for claim
    /// @param claimIndex Claim index for a particular user for a week
    /// @param walletAddress Token owner wallet address
    /// @param signature Signature from signer wallet
    function isSignerVerifiedFromSignature (
        uint256 weekNumber,
        uint256 claimIndex,
        address walletAddress,
        bytes calldata signature
    ) external returns (bool);

    /// @notice Generate random number from Chainlink
    /// @param _weekNumber Number of the week
    /// @return requestId Chainlink requestId
    function generateChainLinkRandomNumbers(uint256 _weekNumber) external returns (uint256 requestId);

    /// @notice Get weekly random numbers for specific week
    /// @param _weekNumber The number of the week
    function getWeeklyRandomNumbers(uint256 _weekNumber) external view returns (uint256[] memory randomNumbers);
}

File 6 of 10 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 7 of 10 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 8 of 10 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 9 of 10 : PxUtils.sol
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.16;

contract PxUtils {
    modifier noContracts() {
        uint256 size;
        address acc = msg.sender;
        assembly {
            size := extcodesize(acc)
        }
        require(msg.sender == tx.origin, "tx.origin != msg.sender");
        require(size == 0, "Contract calls are not allowed");
        _;
    }

    function _uncheckedInc(uint256 value) internal pure returns (uint256) {
        unchecked {
            return value + 1;
        }
    }

    function getRandomNumber() internal view returns (uint256) {
        uint256 randomNumber = uint256(
            keccak256(
                abi.encodePacked(
                    block.timestamp +
                        block.difficulty +
                        ((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (block.timestamp)) +
                        block.gaslimit +
                        ((uint256(keccak256(abi.encodePacked(msg.sender)))) / (block.timestamp)) +
                        block.number
                )
            )
        );

        return randomNumber;
    }
}

File 10 of 10 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_pxChainlinkContractAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"InsufficientToken","type":"error"},{"inputs":[],"name":"InvalidClaimingPeriod","type":"error"},{"inputs":[],"name":"InvalidDuration","type":"error"},{"inputs":[],"name":"InvalidInput","type":"error"},{"inputs":[],"name":"InvalidLength","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidTimeStamp","type":"error"},{"inputs":[],"name":"InvalidTreasureIndex","type":"error"},{"inputs":[],"name":"InvalidUpdationPeriod","type":"error"},{"inputs":[],"name":"InvalidWeekNumber","type":"error"},{"inputs":[],"name":"NotAWinner","type":"error"},{"inputs":[],"name":"NotAdmin","type":"error"},{"inputs":[],"name":"NotModerator","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"weekNumber","type":"uint256"},{"indexed":false,"internalType":"address","name":"userWallet","type":"address"},{"indexed":false,"internalType":"address","name":"collectionAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenType","type":"uint256"}],"name":"TreasureTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"weekNumber","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"tripWinners","type":"address[]"}],"name":"WeeklyWinnersSet","type":"event"},{"inputs":[],"name":"ERC_1155_TYPE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERC_721_TYPE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"collectionAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"claimedToken","type":"uint256"},{"internalType":"uint8","name":"contractType","type":"uint8"},{"internalType":"uint8","name":"treasureType","type":"uint8"}],"internalType":"struct PxWeekManager.Treasure","name":"_treasure","type":"tuple"}],"name":"addSponsoredTripTreasure","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"collectionAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"claimedToken","type":"uint256"},{"internalType":"uint8","name":"contractType","type":"uint8"},{"internalType":"uint8","name":"treasureType","type":"uint8"}],"internalType":"struct PxWeekManager.Treasure","name":"_treasure","type":"tuple"}],"name":"addTreasures","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"adminWallets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_weekNumber","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"claimTreasure","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_weekNumber","type":"uint256"}],"name":"generateChainLinkRandomNumbers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getTreasureById","outputs":[{"components":[{"internalType":"address","name":"collectionAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"claimedToken","type":"uint256"},{"internalType":"uint8","name":"contractType","type":"uint8"},{"internalType":"uint8","name":"treasureType","type":"uint8"}],"internalType":"struct PxWeekManager.Treasure","name":"tmp","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasures","outputs":[{"components":[{"internalType":"address","name":"collectionAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"claimedToken","type":"uint256"},{"internalType":"uint8","name":"contractType","type":"uint8"},{"internalType":"uint8","name":"treasureType","type":"uint8"}],"internalType":"struct PxWeekManager.Treasure[]","name":"tmp","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_weekNumber","type":"uint256"}],"name":"getWeekInfo","outputs":[{"components":[{"internalType":"address[]","name":"tripWinners","type":"address[]"},{"internalType":"uint256[]","name":"randomNumbers","type":"uint256[]"}],"internalType":"struct PxWeekManager.WeekData","name":"week","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_weekNumber","type":"uint256"},{"internalType":"address","name":"_walletAddress","type":"address"}],"name":"getWeeklyClaimedCount","outputs":[{"internalType":"uint8","name":"count","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_weekNumber","type":"uint256"}],"name":"getWeeklyDistributions","outputs":[{"components":[{"internalType":"uint8","name":"treasureIndex","type":"uint8"},{"internalType":"uint16","name":"totalSupply","type":"uint16"}],"internalType":"struct PxWeekManager.TreasureDistribution[]","name":"tmp","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"moderatorWallets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pxChainlinkManagerContract","outputs":[{"internalType":"contract IPxChainlinkManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_walletAddress","type":"address"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"setAdminWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_walletAddress","type":"address"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"setModeratorWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_previousWinners","type":"address[]"},{"internalType":"bool[]","name":"_flags","type":"bool[]"}],"name":"setSponsoredTripWinnerMap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_walletAddress","type":"address"}],"name":"setVaultWalletAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_numberOfWeeks","type":"uint256"},{"internalType":"uint256","name":"_startTimeStamp","type":"uint256"},{"internalType":"uint256","name":"_prizeUpdationDuration","type":"uint256"},{"internalType":"uint256","name":"_winnerUpdationDuration","type":"uint256"},{"internalType":"uint256","name":"_weeklyDuration","type":"uint256"}],"name":"setWeeklyTimeStamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_weekNumber","type":"uint256"},{"internalType":"uint8[]","name":"_treasureindexes","type":"uint8[]"},{"internalType":"uint16[]","name":"_treasureCounts","type":"uint16[]"},{"internalType":"uint8","name":"_sponsoredTripsCount","type":"uint8"}],"name":"setWeeklyTreasureDistribution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pxChainlinkContractAddress","type":"address"}],"name":"setpxChainlinkManagerContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sponsoredTrip","outputs":[{"internalType":"address","name":"collectionAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"claimedToken","type":"uint256"},{"internalType":"uint8","name":"contractType","type":"uint8"},{"internalType":"uint8","name":"treasureType","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"sponsoredTripWinners","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTreasureCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWeek","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"treasures","outputs":[{"internalType":"address","name":"collectionAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"claimedToken","type":"uint256"},{"internalType":"uint8","name":"contractType","type":"uint8"},{"internalType":"uint8","name":"treasureType","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"components":[{"internalType":"address","name":"collectionAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"claimedToken","type":"uint256"},{"internalType":"uint8","name":"contractType","type":"uint8"},{"internalType":"uint8","name":"treasureType","type":"uint8"}],"internalType":"struct PxWeekManager.Treasure","name":"_treasure","type":"tuple"}],"name":"updateTreasure","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_weekNumber","type":"uint256"},{"internalType":"uint256","name":"_startTimeStamp","type":"uint256"},{"internalType":"uint256","name":"_prizeUpdationDuration","type":"uint256"},{"internalType":"uint256","name":"_winnerUpdationDuration","type":"uint256"},{"internalType":"uint256","name":"_weeklyDuration","type":"uint256"}],"name":"updateWeeklyTimeStamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_weekNumber","type":"uint256"},{"internalType":"address[]","name":"_winners","type":"address[]"},{"internalType":"uint8[]","name":"_treasureCounts","type":"uint8[]"}],"name":"updateWeeklyWinners","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultWalletAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"weekInfos","outputs":[{"internalType":"uint256","name":"startTimeStamp","type":"uint256"},{"internalType":"uint256","name":"ticketDrawTimeStamp","type":"uint256"},{"internalType":"uint256","name":"claimStartTimeStamp","type":"uint256"},{"internalType":"uint256","name":"endTimeStamp","type":"uint256"},{"internalType":"uint256","name":"remainingSupply","type":"uint256"},{"internalType":"uint8","name":"treasureCount","type":"uint8"},{"internalType":"uint8","name":"sponsoredTripsCount","type":"uint8"},{"internalType":"uint8","name":"availabletripsCount","type":"uint8"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b5060405162006056380380620060568339818101604052810190620000379190620001dd565b620000576200004b620000a760201b60201c565b620000af60201b60201c565b600160088190555080600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506200020f565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620001a58262000178565b9050919050565b620001b78162000198565b8114620001c357600080fd5b50565b600081519050620001d781620001ac565b92915050565b600060208284031215620001f657620001f562000173565b5b60006200020684828501620001c6565b91505092915050565b615e37806200021f6000396000f3fe608060405234801561001057600080fd5b50600436106102055760003560e01c8063719e24c01161011a578063ac70a1ef116100ad578063d046577d1161007c578063d046577d146105b9578063dde824a8146105d5578063eef3833c14610605578063f2fde38b14610639578063fbb6f4891461065557610205565b8063ac70a1ef14610545578063b56d323514610563578063b77d24f514610581578063c5ea3cc91461059d57610205565b806392f954df116100e957806392f954df146104d3578063a0ad0ed9146104ef578063a2d5acac1461050b578063ac16fc261461052957610205565b8063719e24c01461045b57806372abf36c146104775780638da5cb5b1461049957806391e0cdbb146104b757610205565b80632ab804971161019d578063379a8b5f1161016c578063379a8b5f146103b75780633c090d48146103e75780634f6e54d4146104035780636063459114610421578063715018a61461045157610205565b80632ab80497146103025780632d3651db146103325780632d6ab7d51461036257806336dfa5561461038057610205565b80631456b66d116101d95780631456b66d1461027c578063171ccfd714610298578063238b045a146102b65780632aa3a4ba146102d257610205565b8062e4e63b1461020a57806303bc039314610226578063079eb0c1146102425780630eb1bb7b14610260575b600080fd5b610224600480360381019061021f91906142b4565b610685565b005b610240600480360381019061023b91906145e2565b61092e565b005b61024a610fc3565b60405161025791906146cc565b60405180910390f35b61027a600480360381019061027591906142b4565b610fe9565b005b61029660048036038101906102919190614870565b6111a7565b005b6102a06113e7565b6040516102ad91906148db565b60405180910390f35b6102d060048036038101906102cb91906148f6565b6113ed565b005b6102ec60048036038101906102e7919061493f565b61159b565b6040516102f99190614b2c565b60405180910390f35b61031c60048036038101906103179190614b4e565b6116f4565b6040516103299190614b96565b60405180910390f35b61034c60048036038101906103479190614b4e565b611714565b6040516103599190614b96565b60405180910390f35b61036a611734565b60405161037791906148db565b60405180910390f35b61039a6004803603810190610395919061493f565b61173a565b6040516103ae989796959493929190614bc0565b60405180910390f35b6103d160048036038101906103cc919061493f565b6117a9565b6040516103de9190614cd6565b60405180910390f35b61040160048036038101906103fc9190614b4e565b6118d2565b005b61040b61191e565b6040516104189190614cf8565b60405180910390f35b61043b60048036038101906104369190614d13565b611923565b6040516104489190614cf8565b60405180910390f35b610459611991565b005b61047560048036038101906104709190614d7f565b6119a5565b005b61047f611a08565b604051610490959493929190614dce565b60405180910390f35b6104a1611a66565b6040516104ae9190614e21565b60405180910390f35b6104d160048036038101906104cc91906148f6565b611a8f565b005b6104ed60048036038101906104e89190614d7f565b611ce8565b005b61050960048036038101906105049190614f39565b611d4b565b005b6105136120c9565b6040516105209190614e21565b60405180910390f35b610543600480360381019061053e9190614b4e565b6120ef565b005b61054d61213b565b60405161055a9190615123565b60405180910390f35b61056b612306565b6040516105789190614cf8565b60405180910390f35b61059b600480360381019061059691906151a0565b61230b565b005b6105b760048036038101906105b291906152c3565b6127bf565b005b6105d360048036038101906105ce919061493f565b61292f565b005b6105ef60048036038101906105ea919061493f565b612ac9565b6040516105fc9190615428565b60405180910390f35b61061f600480360381019061061a919061493f565b612c33565b604051610630959493929190614dce565b60405180910390f35b610653600480360381019061064e9190614b4e565b612ca3565b005b61066f600480360381019061066a9190614b4e565b612d26565b60405161067c9190614b96565b60405180910390f35b33600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610709576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85600081148061071a575060035481115b15610751576040517f46e6d5da00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b838561075d9190615479565b8311610795576040517f7616640100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600187141580156107c85750600460006001896107b291906154ad565b8152602001908152602001600020600301548611155b156107ff576040517f4b3d204d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600354871415801561084a57506004600060018961081d9190615479565b8152602001908152602001600020600001546001848861083d9190615479565b61084791906154ad565b10155b15610881576040517f4b3d204d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85600460008981526020019081526020016000206000018190555084866108a89190615479565b60046000898152602001908152602001600020600101819055508385876108cf9190615479565b6108d99190615479565b6004600089815260200190815260200160002060020181905550600183876109019190615479565b61090b91906154ad565b600460008981526020019081526020016000206003018190555050505050505050565b33600660008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166109b2576040517feaa45d6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825182518082146109ef576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560046000828152602001908152602001600020600101544210158015610a2b5750600460008281526020019081526020016000206002015442105b610a61576040517f4b7a7ea200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6004600089815260200190815260200160002060060180549050811015610b5c576000600460008a81526020019081526020016000206006018281548110610aaf57610aae6154e1565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600460008b815260200190815260200160002060070160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550508080610b5490615510565b915050610a64565b506000610b67612d46565b905060008651875183610b7a9190615587565b610b8491906155b8565b82610b8f91906154ad565b9050600080600080600460008e815260200190815260200160002060050160019054906101000a900460ff1660ff1667ffffffffffffffff811115610bd757610bd6614345565b5b604051908082528060200260200182016040528015610c055781602001602082028036833780820191505090505b5090505b8a51841015610ec6578a518503610c1f57600094505b600f60008d8781518110610c3657610c356154e1565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16158015610cb85750600460008e815260200190815260200160002060050160019054906101000a900460ff1660ff1683105b8015610ce1575060008b8681518110610cd457610cd36154e1565b5b602002602001015160ff16115b15610de3576001600460008f815260200190815260200160002060070160008e8881518110610d1357610d126154e1565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508b8581518110610d7f57610d7e6154e1565b5b6020026020010151818481518110610d9a57610d996154e1565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508280610ddf90615510565b9350505b8a8581518110610df657610df56154e1565b5b6020026020010151600460008f815260200190815260200160002060090160008e8881518110610e2957610e286154e1565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff021916908360ff1602179055508a8581518110610e9957610e986154e1565b5b602002602001015160ff1682610eaf9190615479565b915084806001019550508380600101945050610c09565b600460008e815260200190815260200160002060050160019054906101000a900460ff1660ff16600460008f815260200190815260200160002060040154610f0e9190615479565b821115610f50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f479061566f565b60405180910390fd5b80600460008f81526020019081526020016000206006019080519060200190610f7a9291906140e9565b507f2d2076d8455ccee841675580c81ac35d8b17f201da64e8866611bd7a40c78cc68d82604051610fac9291906156fe565b60405180910390a150505050505050505050505050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b33600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661106d576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82846110799190615479565b82116110b1576040517f7616640100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8681101561119e57600360008154809291906110cf90615510565b9190505550856004600060035481526020019081526020016000206000018190555084866110fd9190615479565b600460006003548152602001908152602001600020600101819055508385876111269190615479565b6111309190615479565b600460006003548152602001908152602001600020600201819055506001838761115a9190615479565b61116491906154ad565b60046000600354815260200190815260200160002060030181905550828661118c9190615479565b955061119781612e1b565b90506110b4565b50505050505050565b33600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661122b576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600160ff16816080015160ff16141580156112525750600260ff16816080015160ff1614155b15611289576040517fb4fa3fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160ff16816080015160ff161480156112a857506000816040015151115b806112ce5750600260ff16816080015160ff161480156112cd57506000816040015151145b5b15611305576040517fb4fa3fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000836060018181525050826002600086815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002019080519060200190611391929190614173565b506060820151816003015560808201518160040160006101000a81548160ff021916908360ff16021790555060a08201518160040160016101000a81548160ff021916908360ff16021790555090505050505050565b60015481565b33600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611471576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082606001511415806114905750600160ff16826080015160ff1614155b806114a057506000826040015151115b156114d7576040517fb4fa3fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600a60008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002019080519060200190611547929190614173565b506060820151816003015560808201518160040160006101000a81548160ff021916908360ff16021790555060a08201518160040160016101000a81548160ff021916908360ff1602179055509050505050565b6115a36141c0565b6004600083815260200190815260200160002060060180548060200260200160405190810160405280929190818152602001828054801561163957602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116115ef575b50505050508160000181905250600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633dcec1a8836040518263ffffffff1660e01b81526004016116a191906148db565b600060405180830381865afa1580156116be573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906116e791906157da565b8160200181905250919050565b60056020528060005260406000206000915054906101000a900460ff1681565b600f6020528060005260406000206000915054906101000a900460ff1681565b60035481565b60046020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050160009054906101000a900460ff16908060050160019054906101000a900460ff16908060050160029054906101000a900460ff16905088565b6117b16141da565b600260008381526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820180548060200260200160405190810160405280929190818152602001828054801561187e57602002820191906000526020600020905b81548152602001906001019080831161186a575b50505050508152602001600382015481526020016004820160009054906101000a900460ff1660ff1660ff1681526020016004820160019054906101000a900460ff1660ff1660ff16815250509050919050565b6118da612e28565b80600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600281565b60006004600084815260200190815260200160002060090160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900460ff16905092915050565b611999612e28565b6119a36000612ea6565b565b6119ad612e28565b80600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600a8060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060030154908060040160009054906101000a900460ff16908060040160019054906101000a900460ff16905085565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b33600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611b13576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600160ff16816080015160ff1614158015611b3a5750600260ff16816080015160ff1614155b15611b71576040517fb4fa3fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160ff16816080015160ff16148015611b9057506000816040015151115b80611bb65750600260ff16816080015160ff16148015611bb557506000816040015151145b5b15611bed576040517fb4fa3fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016000815480929190611c0090615510565b919050555060008360600181815250508260026000600154815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002019080519060200190611c93929190614173565b506060820151816003015560808201518160040160006101000a81548160ff021916908360ff16021790555060a08201518160040160016101000a81548160ff021916908360ff160217905550905050505050565b611cf0612e28565b80600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b33600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611dcf576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460046000828152602001908152602001600020600001544210158015611e0b5750600460008281526020019081526020016000206001015442105b611e41576040517f4b7a7ea200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518451808214611e7e576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600460008a81526020019081526020016000209050858160050160016101000a81548160ff021916908360ff160217905550858160050160026101000a81548160ff021916908360ff16021790555060008160050160006101000a81548160ff021916908360ff16021790555060005b88518110156120bd576000898281518110611f0e57611f0d6154e1565b5b602002602001015160ff161480611f435750600154898281518110611f3657611f356154e1565b5b602002602001015160ff16115b15611f7a576040517fa549bb0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600501600081819054906101000a900460ff1680929190611f9b90615823565b91906101000a81548160ff021916908360ff16021790555050888181518110611fc757611fc66154e1565b5b60200260200101518260080160008460050160009054906101000a900460ff1660ff16815260200190815260200160002060000160006101000a81548160ff021916908360ff160217905550878181518110612026576120256154e1565b5b60200260200101518260080160008460050160009054906101000a900460ff1660ff16815260200190815260200160002060000160016101000a81548161ffff021916908361ffff160217905550878181518110612087576120866154e1565b5b602002602001015161ffff168260040160008282546120a69190615479565b925050819055506120b681612e1b565b9050611ef0565b50505050505050505050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6120f7612e28565b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6060600060015467ffffffffffffffff81111561215b5761215a614345565b5b60405190808252806020026020018201604052801561219457816020015b6121816141da565b8152602001906001900390816121795790505b5090506000600190505b60015481116122fe57600260008281526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820180548060200260200160405190810160405280929190818152602001828054801561227457602002820191906000526020600020905b815481526020019060010190808311612260575b50505050508152602001600382015481526020016004820160009054906101000a900460ff1660ff1660ff1681526020016004820160019054906101000a900460ff1660ff1660ff1681525050826001836122cf91906154ad565b815181106122e0576122df6154e1565b5b602002602001018190525080806122f690615510565b91505061219e565b508091505090565b600181565b600080339050803b91503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612383576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237a90615898565b60405180910390fd5b600082146123c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123bd90615904565b60405180910390fd5b6123ce612f6a565b6004600086815260200190815260200160002060020154421015801561240a575060046000868152602001908152602001600020600301544211155b612440576040517f5f8cf72a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663eae07d9d87600460008a815260200190815260200160002060090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900460ff163389896040518663ffffffff1660e01b81526004016125089594939291906159a2565b6020604051808303816000875af1158015612527573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254b9190615a05565b905080612584576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006004600088815260200190815260200160002060090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1660ff1603612624576040517fb19a9f8200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004600087815260200190815260200160002060090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1660ff166004600088815260200190815260200160002060090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900460ff1660ff1603612729576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006004600088815260200190815260200160002060090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900460ff1660ff16036127a5576127a086612fb9565b6127af565b6127ae86613682565b5b506127b8613e3f565b5050505050565b33600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612843576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82518251808214612880576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b84518110156129275784818151811061289f5761289e6154e1565b5b6020026020010151600f60008884815181106128be576128bd6154e1565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061292081612e1b565b9050612883565b505050505050565b33600660008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166129b3576040517feaa45d6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600460008281526020019081526020016000206001015442101580156129ef5750600460008281526020019081526020016000206002015442105b612a25576040517f4b7a7ea200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d046577d846040518263ffffffff1660e01b8152600401612a8091906148db565b6020604051808303816000875af1158015612a9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac39190615a32565b50505050565b606060006004600084815260200190815260200160002060050160009054906101000a900460ff1660ff1667ffffffffffffffff811115612b0d57612b0c614345565b5b604051908082528060200260200182016040528015612b4657816020015b612b3361422c565b815260200190600190039081612b2b5790505b5090506000600190505b6004600085815260200190815260200160002060050160009054906101000a900460ff1660ff168111612c29576004600085815260200190815260200160002060080160008281526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff1660ff1660ff1681526020016000820160019054906101000a900461ffff1661ffff1661ffff168152505082600183612bfa91906154ad565b81518110612c0b57612c0a6154e1565b5b60200260200101819052508080612c2190615510565b915050612b50565b5080915050919050565b60026020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060030154908060040160009054906101000a900460ff16908060040160019054906101000a900460ff16905085565b612cab612e28565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1190615ad1565b60405180910390fd5b612d2381612ea6565b50565b60066020528060005260406000206000915054906101000a900460ff1681565b600080434233604051602001612d5c9190615b39565b6040516020818303038152906040528051906020012060001c612d7f9190615587565b454241604051602001612d929190615b8f565b6040516020818303038152906040528051906020012060001c612db59190615587565b4442612dc19190615479565b612dcb9190615479565b612dd59190615479565b612ddf9190615479565b612de99190615479565b604051602001612df99190615bcb565b6040516020818303038152906040528051906020012060001c90508091505090565b6000600182019050919050565b612e30613e49565b73ffffffffffffffffffffffffffffffffffffffff16612e4e611a66565b73ffffffffffffffffffffffffffffffffffffffff1614612ea4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9b90615c32565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600260085403612faf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fa690615c9e565b60405180910390fd5b6002600881905550565b60006004600083815260200190815260200160002090508060070160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156132ab576001600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060008160070160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508060090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001600181819054906101000a900460ff168092919060010191906101000a81548160ff021916908360ff1602179055505080600501600281819054906101000a900460ff16809291906001900391906101000a81548160ff021916908360ff16021790555050600a600301600081548092919060010191905055506132a682600a6040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820180548060200260200160405190810160405280929190818152602001828054801561325457602002820191906000526020600020905b815481526020019060010190808311613240575b50505050508152602001600382015481526020016004820160009054906101000a900460ff1660ff1660ff1681526020016004820160019054906101000a900460ff1660ff1660ff1681525050613e51565b61367e565b60006132b5612d46565b90506000600183600401548460040154846132d09190615587565b6132da91906155b8565b836132e591906154ad565b6132ef9190615479565b90506000806000600190505b8560050160009054906101000a900460ff1660ff16811161339857600086600801600083815260200190815260200160002060000160019054906101000a900461ffff1661ffff1603156133885785600801600082815260200190815260200160002060000160019054906101000a900461ffff16820191508161ffff16841161338757809250613398565b5b61339181612e1b565b90506132fb565b50600085600801600084815260200190815260200160002060000160009054906101000a900460ff1660ff16905060018660090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006002600085815260200190815260200160002060040160019054906101000a900460ff1660ff16815260200190815260200160002060006101000a81548160ff021916908315150217905550856008016000848152602001908152602001600020600001600181819054906101000a900461ffff16809291906001900391906101000a81548161ffff021916908361ffff160217905550508560090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001600181819054906101000a900460ff168092919060010191906101000a81548160ff021916908360ff16021790555050856004016000815480929190600190039190505550600260008281526020019081526020016000206003016000815480929190600101919050555061367887600260008481526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820180548060200260200160405190810160405280929190818152602001828054801561362657602002820191906000526020600020905b815481526020019060010190808311613612575b50505050508152602001600382015481526020016004820160009054906101000a900460ff1660ff1660ff1681526020016004820160019054906101000a900460ff1660ff1660ff1681525050613e51565b50505050505b5050565b60006004600083815260200190815260200160002090506000806000600190505b8360050160009054906101000a900460ff1660ff1681116137e65760006002600086600801600085815260200190815260200160002060000160009054906101000a900460ff1660ff16815260200190815260200160002060040160019054906101000a900460ff1660ff1690508460090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600082815260200190815260200160002060009054906101000a900460ff16156137a95784600801600083815260200190815260200160002060000160019054906101000a900461ffff16830192506137d5565b84600801600083815260200190815260200160002060000160019054906101000a900461ffff16840193505b506137df81612e1b565b90506136a3565b5060006137f1612d46565b905060008085600401548461ffff16036139b057600060018561ffff168661ffff168661381e9190615587565b61382891906155b8565b8561383391906154ad565b61383d9190615479565b90506000600190505b8760050160009054906101000a900460ff1660ff1681116139a9576000600260008a600801600085815260200190815260200160002060000160009054906101000a900460ff1660ff16815260200190815260200160002060040160019054906101000a900460ff1660ff169050600089600801600084815260200190815260200160002060000160019054906101000a900461ffff1661ffff16148061394d57508860090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600082815260200190815260200160002060009054906101000a900460ff16155b156139585750613999565b88600801600083815260200190815260200160002060000160019054906101000a900461ffff1661ffff168401935083831161399757819450506139a9565b505b6139a281612e1b565b9050613846565b5050613b56565b600060018661ffff168761ffff16866139c99190615587565b6139d391906155b8565b856139de91906154ad565b6139e89190615479565b90506000600190505b8760050160009054906101000a900460ff1660ff168111613b53576000600260008a600801600085815260200190815260200160002060000160009054906101000a900460ff1660ff16815260200190815260200160002060040160019054906101000a900460ff1660ff169050600089600801600084815260200190815260200160002060000160019054906101000a900461ffff1661ffff161480613af757508860090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600082815260200190815260200160002060009054906101000a900460ff165b15613b025750613b43565b88600801600083815260200190815260200160002060000160019054906101000a900461ffff1661ffff1684019350838311613b415781945050613b53565b505b613b4c81612e1b565b90506139f1565b50505b600086600801600084815260200190815260200160002060000160009054906101000a900460ff1660ff16905060018760090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006002600085815260200190815260200160002060040160019054906101000a900460ff1660ff16815260200190815260200160002060006101000a81548160ff021916908315150217905550866008016000848152602001908152602001600020600001600181819054906101000a900461ffff16809291906001900391906101000a81548161ffff021916908361ffff160217905550508660090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001600181819054906101000a900460ff168092919060010191906101000a81548160ff021916908360ff160217905550508660040160008154809291906001900391905055506002600082815260200190815260200160002060030160008154809291906001019190505550613e3588600260008481526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820154815260200160028201805480602002602001604051908101604052809291908181526020018280548015613de357602002820191906000526020600020905b815481526020019060010190808311613dcf575b50505050508152602001600382015481526020016004820160009054906101000a900460ff1660ff1660ff1681526020016004820160019054906101000a900460ff1660ff1660ff1681525050613e51565b5050505050505050565b6001600881905550565b600033905090565b600160ff16816080015160ff1603613f51576000816000015190508073ffffffffffffffffffffffffffffffffffffffff1663f242432a600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633856020015160016040518563ffffffff1660e01b8152600401613ed29493929190615d1f565b600060405180830381600087803b158015613eec57600080fd5b505af1158015613f00573d6000803e3d6000fd5b505050507f7a9968751a59a2a8b2b71d8cca320739a4d92097045da1ce8cdd5478e2fcd7138333846000015185602001518660800151604051613f47959493929190615d77565b60405180910390a1505b600260ff16816080015160ff16036140e55760008160000151905081606001518260400151511015613faf576040517f675cae3800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166323b872dd600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff163385604001516001876060015161400591906154ad565b81518110614016576140156154e1565b5b60200260200101516040518463ffffffff1660e01b815260040161403c93929190615dca565b600060405180830381600087803b15801561405657600080fd5b505af115801561406a573d6000803e3d6000fd5b505050507f7a9968751a59a2a8b2b71d8cca320739a4d92097045da1ce8cdd5478e2fcd713833384600001518560400151600187606001516140ac91906154ad565b815181106140bd576140bc6154e1565b5b602002602001015186608001516040516140db959493929190615d77565b60405180910390a1505b5050565b828054828255906000526020600020908101928215614162579160200282015b828111156141615782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190614109565b5b50905061416f919061424d565b5090565b8280548282559060005260206000209081019282156141af579160200282015b828111156141ae578251825591602001919060010190614193565b5b5090506141bc919061424d565b5090565b604051806040016040528060608152602001606081525090565b6040518060c00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016060815260200160008152602001600060ff168152602001600060ff1681525090565b6040518060400160405280600060ff168152602001600061ffff1681525090565b5b8082111561426657600081600090555060010161424e565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6142918161427e565b811461429c57600080fd5b50565b6000813590506142ae81614288565b92915050565b600080600080600060a086880312156142d0576142cf614274565b5b60006142de8882890161429f565b95505060206142ef8882890161429f565b94505060406143008882890161429f565b93505060606143118882890161429f565b92505060806143228882890161429f565b9150509295509295909350565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61437d82614334565b810181811067ffffffffffffffff8211171561439c5761439b614345565b5b80604052505050565b60006143af61426a565b90506143bb8282614374565b919050565b600067ffffffffffffffff8211156143db576143da614345565b5b602082029050602081019050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061441c826143f1565b9050919050565b61442c81614411565b811461443757600080fd5b50565b60008135905061444981614423565b92915050565b600061446261445d846143c0565b6143a5565b90508083825260208201905060208402830185811115614485576144846143ec565b5b835b818110156144ae578061449a888261443a565b845260208401935050602081019050614487565b5050509392505050565b600082601f8301126144cd576144cc61432f565b5b81356144dd84826020860161444f565b91505092915050565b600067ffffffffffffffff82111561450157614500614345565b5b602082029050602081019050919050565b600060ff82169050919050565b61452881614512565b811461453357600080fd5b50565b6000813590506145458161451f565b92915050565b600061455e614559846144e6565b6143a5565b90508083825260208201905060208402830185811115614581576145806143ec565b5b835b818110156145aa57806145968882614536565b845260208401935050602081019050614583565b5050509392505050565b600082601f8301126145c9576145c861432f565b5b81356145d984826020860161454b565b91505092915050565b6000806000606084860312156145fb576145fa614274565b5b60006146098682870161429f565b935050602084013567ffffffffffffffff81111561462a57614629614279565b5b614636868287016144b8565b925050604084013567ffffffffffffffff81111561465757614656614279565b5b614663868287016145b4565b9150509250925092565b6000819050919050565b600061469261468d614688846143f1565b61466d565b6143f1565b9050919050565b60006146a482614677565b9050919050565b60006146b682614699565b9050919050565b6146c6816146ab565b82525050565b60006020820190506146e160008301846146bd565b92915050565b600080fd5b600080fd5b600067ffffffffffffffff82111561470c5761470b614345565b5b602082029050602081019050919050565b600061473061472b846146f1565b6143a5565b90508083825260208201905060208402830185811115614753576147526143ec565b5b835b8181101561477c5780614768888261429f565b845260208401935050602081019050614755565b5050509392505050565b600082601f83011261479b5761479a61432f565b5b81356147ab84826020860161471d565b91505092915050565b600060c082840312156147ca576147c96146e7565b5b6147d460c06143a5565b905060006147e48482850161443a565b60008301525060206147f88482850161429f565b602083015250604082013567ffffffffffffffff81111561481c5761481b6146ec565b5b61482884828501614786565b604083015250606061483c8482850161429f565b606083015250608061485084828501614536565b60808301525060a061486484828501614536565b60a08301525092915050565b6000806040838503121561488757614886614274565b5b60006148958582860161429f565b925050602083013567ffffffffffffffff8111156148b6576148b5614279565b5b6148c2858286016147b4565b9150509250929050565b6148d58161427e565b82525050565b60006020820190506148f060008301846148cc565b92915050565b60006020828403121561490c5761490b614274565b5b600082013567ffffffffffffffff81111561492a57614929614279565b5b614936848285016147b4565b91505092915050565b60006020828403121561495557614954614274565b5b60006149638482850161429f565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6149a181614411565b82525050565b60006149b38383614998565b60208301905092915050565b6000602082019050919050565b60006149d78261496c565b6149e18185614977565b93506149ec83614988565b8060005b83811015614a1d578151614a0488826149a7565b9750614a0f836149bf565b9250506001810190506149f0565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614a5f8161427e565b82525050565b6000614a718383614a56565b60208301905092915050565b6000602082019050919050565b6000614a9582614a2a565b614a9f8185614a35565b9350614aaa83614a46565b8060005b83811015614adb578151614ac28882614a65565b9750614acd83614a7d565b925050600181019050614aae565b5085935050505092915050565b60006040830160008301518482036000860152614b0582826149cc565b91505060208301518482036020860152614b1f8282614a8a565b9150508091505092915050565b60006020820190508181036000830152614b468184614ae8565b905092915050565b600060208284031215614b6457614b63614274565b5b6000614b728482850161443a565b91505092915050565b60008115159050919050565b614b9081614b7b565b82525050565b6000602082019050614bab6000830184614b87565b92915050565b614bba81614512565b82525050565b600061010082019050614bd6600083018b6148cc565b614be3602083018a6148cc565b614bf060408301896148cc565b614bfd60608301886148cc565b614c0a60808301876148cc565b614c1760a0830186614bb1565b614c2460c0830185614bb1565b614c3160e0830184614bb1565b9998505050505050505050565b614c4781614512565b82525050565b600060c083016000830151614c656000860182614998565b506020830151614c786020860182614a56565b5060408301518482036040860152614c908282614a8a565b9150506060830151614ca56060860182614a56565b506080830151614cb86080860182614c3e565b5060a0830151614ccb60a0860182614c3e565b508091505092915050565b60006020820190508181036000830152614cf08184614c4d565b905092915050565b6000602082019050614d0d6000830184614bb1565b92915050565b60008060408385031215614d2a57614d29614274565b5b6000614d388582860161429f565b9250506020614d498582860161443a565b9150509250929050565b614d5c81614b7b565b8114614d6757600080fd5b50565b600081359050614d7981614d53565b92915050565b60008060408385031215614d9657614d95614274565b5b6000614da48582860161443a565b9250506020614db585828601614d6a565b9150509250929050565b614dc881614411565b82525050565b600060a082019050614de36000830188614dbf565b614df060208301876148cc565b614dfd60408301866148cc565b614e0a6060830185614bb1565b614e176080830184614bb1565b9695505050505050565b6000602082019050614e366000830184614dbf565b92915050565b600067ffffffffffffffff821115614e5757614e56614345565b5b602082029050602081019050919050565b600061ffff82169050919050565b614e7f81614e68565b8114614e8a57600080fd5b50565b600081359050614e9c81614e76565b92915050565b6000614eb5614eb084614e3c565b6143a5565b90508083825260208201905060208402830185811115614ed857614ed76143ec565b5b835b81811015614f015780614eed8882614e8d565b845260208401935050602081019050614eda565b5050509392505050565b600082601f830112614f2057614f1f61432f565b5b8135614f30848260208601614ea2565b91505092915050565b60008060008060808587031215614f5357614f52614274565b5b6000614f618782880161429f565b945050602085013567ffffffffffffffff811115614f8257614f81614279565b5b614f8e878288016145b4565b935050604085013567ffffffffffffffff811115614faf57614fae614279565b5b614fbb87828801614f0b565b9250506060614fcc87828801614536565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600060c08301600083015161501c6000860182614998565b50602083015161502f6020860182614a56565b50604083015184820360408601526150478282614a8a565b915050606083015161505c6060860182614a56565b50608083015161506f6080860182614c3e565b5060a083015161508260a0860182614c3e565b508091505092915050565b60006150998383615004565b905092915050565b6000602082019050919050565b60006150b982614fd8565b6150c38185614fe3565b9350836020820285016150d585614ff4565b8060005b8581101561511157848403895281516150f2858261508d565b94506150fd836150a1565b925060208a019950506001810190506150d9565b50829750879550505050505092915050565b6000602082019050818103600083015261513d81846150ae565b905092915050565b600080fd5b60008083601f8401126151605761515f61432f565b5b8235905067ffffffffffffffff81111561517d5761517c615145565b5b602083019150836001820283011115615199576151986143ec565b5b9250929050565b6000806000604084860312156151b9576151b8614274565b5b60006151c78682870161429f565b935050602084013567ffffffffffffffff8111156151e8576151e7614279565b5b6151f48682870161514a565b92509250509250925092565b600067ffffffffffffffff82111561521b5761521a614345565b5b602082029050602081019050919050565b600061523f61523a84615200565b6143a5565b90508083825260208201905060208402830185811115615262576152616143ec565b5b835b8181101561528b57806152778882614d6a565b845260208401935050602081019050615264565b5050509392505050565b600082601f8301126152aa576152a961432f565b5b81356152ba84826020860161522c565b91505092915050565b600080604083850312156152da576152d9614274565b5b600083013567ffffffffffffffff8111156152f8576152f7614279565b5b615304858286016144b8565b925050602083013567ffffffffffffffff81111561532557615324614279565b5b61533185828601615295565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61537081614e68565b82525050565b60408201600082015161538c6000850182614c3e565b50602082015161539f6020850182615367565b50505050565b60006153b18383615376565b60408301905092915050565b6000602082019050919050565b60006153d58261533b565b6153df8185615346565b93506153ea83615357565b8060005b8381101561541b57815161540288826153a5565b975061540d836153bd565b9250506001810190506153ee565b5085935050505092915050565b6000602082019050818103600083015261544281846153ca565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006154848261427e565b915061548f8361427e565b92508282019050808211156154a7576154a661544a565b5b92915050565b60006154b88261427e565b91506154c38361427e565b92508282039050818111156154db576154da61544a565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061551b8261427e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361554d5761554c61544a565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006155928261427e565b915061559d8361427e565b9250826155ad576155ac615558565b5b828204905092915050565b60006155c38261427e565b91506155ce8361427e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156156075761560661544a565b5b828202905092915050565b600082825260208201905092915050565b7f496e76616c696420547265617375726520416d6f756e74000000000000000000600082015250565b6000615659601783615612565b915061566482615623565b602082019050919050565b600060208201905081810360008301526156888161564c565b9050919050565b600082825260208201905092915050565b60006156ab8261496c565b6156b5818561568f565b93506156c083614988565b8060005b838110156156f15781516156d888826149a7565b97506156e3836149bf565b9250506001810190506156c4565b5085935050505092915050565b600060408201905061571360008301856148cc565b818103602083015261572581846156a0565b90509392505050565b60008151905061573d81614288565b92915050565b6000615756615751846146f1565b6143a5565b90508083825260208201905060208402830185811115615779576157786143ec565b5b835b818110156157a2578061578e888261572e565b84526020840193505060208101905061577b565b5050509392505050565b600082601f8301126157c1576157c061432f565b5b81516157d1848260208601615743565b91505092915050565b6000602082840312156157f0576157ef614274565b5b600082015167ffffffffffffffff81111561580e5761580d614279565b5b61581a848285016157ac565b91505092915050565b600061582e82614512565b915060ff82036158415761584061544a565b5b600182019050919050565b7f74782e6f726967696e20213d206d73672e73656e646572000000000000000000600082015250565b6000615882601783615612565b915061588d8261584c565b602082019050919050565b600060208201905081810360008301526158b181615875565b9050919050565b7f436f6e74726163742063616c6c7320617265206e6f7420616c6c6f7765640000600082015250565b60006158ee601e83615612565b91506158f9826158b8565b602082019050919050565b6000602082019050818103600083015261591d816158e1565b9050919050565b600061593f61593a61593584614512565b61466d565b61427e565b9050919050565b61594f81615924565b82525050565b600082825260208201905092915050565b82818337600083830152505050565b60006159818385615955565b935061598e838584615966565b61599783614334565b840190509392505050565b60006080820190506159b760008301886148cc565b6159c46020830187615946565b6159d16040830186614dbf565b81810360608301526159e4818486615975565b90509695505050505050565b6000815190506159ff81614d53565b92915050565b600060208284031215615a1b57615a1a614274565b5b6000615a29848285016159f0565b91505092915050565b600060208284031215615a4857615a47614274565b5b6000615a568482850161572e565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615abb602683615612565b9150615ac682615a5f565b604082019050919050565b60006020820190508181036000830152615aea81615aae565b9050919050565b60008160601b9050919050565b6000615b0982615af1565b9050919050565b6000615b1b82615afe565b9050919050565b615b33615b2e82614411565b615b10565b82525050565b6000615b458284615b22565b60148201915081905092915050565b6000615b5f826143f1565b9050919050565b6000615b7182615afe565b9050919050565b615b89615b8482615b54565b615b66565b82525050565b6000615b9b8284615b78565b60148201915081905092915050565b6000819050919050565b615bc5615bc08261427e565b615baa565b82525050565b6000615bd78284615bb4565b60208201915081905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615c1c602083615612565b9150615c2782615be6565b602082019050919050565b60006020820190508181036000830152615c4b81615c0f565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000615c88601f83615612565b9150615c9382615c52565b602082019050919050565b60006020820190508181036000830152615cb781615c7b565b9050919050565b6000819050919050565b6000615ce3615cde615cd984615cbe565b61466d565b61427e565b9050919050565b615cf381615cc8565b82525050565b50565b6000615d09600083615955565b9150615d1482615cf9565b600082019050919050565b600060a082019050615d346000830187614dbf565b615d416020830186614dbf565b615d4e60408301856148cc565b615d5b6060830184615cea565b8181036080830152615d6c81615cfc565b905095945050505050565b600060a082019050615d8c60008301886148cc565b615d996020830187614dbf565b615da66040830186614dbf565b615db360608301856148cc565b615dc06080830184615946565b9695505050505050565b6000606082019050615ddf6000830186614dbf565b615dec6020830185614dbf565b615df960408301846148cc565b94935050505056fea264697066735822122056b215dafb4a6e469bd247e592121a6d3ae35354ebae9eceecbafd65591552cf64736f6c634300081000330000000000000000000000000df2d64b5440bf2b4bcc1074ec0e05d6463a9b5c

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102055760003560e01c8063719e24c01161011a578063ac70a1ef116100ad578063d046577d1161007c578063d046577d146105b9578063dde824a8146105d5578063eef3833c14610605578063f2fde38b14610639578063fbb6f4891461065557610205565b8063ac70a1ef14610545578063b56d323514610563578063b77d24f514610581578063c5ea3cc91461059d57610205565b806392f954df116100e957806392f954df146104d3578063a0ad0ed9146104ef578063a2d5acac1461050b578063ac16fc261461052957610205565b8063719e24c01461045b57806372abf36c146104775780638da5cb5b1461049957806391e0cdbb146104b757610205565b80632ab804971161019d578063379a8b5f1161016c578063379a8b5f146103b75780633c090d48146103e75780634f6e54d4146104035780636063459114610421578063715018a61461045157610205565b80632ab80497146103025780632d3651db146103325780632d6ab7d51461036257806336dfa5561461038057610205565b80631456b66d116101d95780631456b66d1461027c578063171ccfd714610298578063238b045a146102b65780632aa3a4ba146102d257610205565b8062e4e63b1461020a57806303bc039314610226578063079eb0c1146102425780630eb1bb7b14610260575b600080fd5b610224600480360381019061021f91906142b4565b610685565b005b610240600480360381019061023b91906145e2565b61092e565b005b61024a610fc3565b60405161025791906146cc565b60405180910390f35b61027a600480360381019061027591906142b4565b610fe9565b005b61029660048036038101906102919190614870565b6111a7565b005b6102a06113e7565b6040516102ad91906148db565b60405180910390f35b6102d060048036038101906102cb91906148f6565b6113ed565b005b6102ec60048036038101906102e7919061493f565b61159b565b6040516102f99190614b2c565b60405180910390f35b61031c60048036038101906103179190614b4e565b6116f4565b6040516103299190614b96565b60405180910390f35b61034c60048036038101906103479190614b4e565b611714565b6040516103599190614b96565b60405180910390f35b61036a611734565b60405161037791906148db565b60405180910390f35b61039a6004803603810190610395919061493f565b61173a565b6040516103ae989796959493929190614bc0565b60405180910390f35b6103d160048036038101906103cc919061493f565b6117a9565b6040516103de9190614cd6565b60405180910390f35b61040160048036038101906103fc9190614b4e565b6118d2565b005b61040b61191e565b6040516104189190614cf8565b60405180910390f35b61043b60048036038101906104369190614d13565b611923565b6040516104489190614cf8565b60405180910390f35b610459611991565b005b61047560048036038101906104709190614d7f565b6119a5565b005b61047f611a08565b604051610490959493929190614dce565b60405180910390f35b6104a1611a66565b6040516104ae9190614e21565b60405180910390f35b6104d160048036038101906104cc91906148f6565b611a8f565b005b6104ed60048036038101906104e89190614d7f565b611ce8565b005b61050960048036038101906105049190614f39565b611d4b565b005b6105136120c9565b6040516105209190614e21565b60405180910390f35b610543600480360381019061053e9190614b4e565b6120ef565b005b61054d61213b565b60405161055a9190615123565b60405180910390f35b61056b612306565b6040516105789190614cf8565b60405180910390f35b61059b600480360381019061059691906151a0565b61230b565b005b6105b760048036038101906105b291906152c3565b6127bf565b005b6105d360048036038101906105ce919061493f565b61292f565b005b6105ef60048036038101906105ea919061493f565b612ac9565b6040516105fc9190615428565b60405180910390f35b61061f600480360381019061061a919061493f565b612c33565b604051610630959493929190614dce565b60405180910390f35b610653600480360381019061064e9190614b4e565b612ca3565b005b61066f600480360381019061066a9190614b4e565b612d26565b60405161067c9190614b96565b60405180910390f35b33600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610709576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85600081148061071a575060035481115b15610751576040517f46e6d5da00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b838561075d9190615479565b8311610795576040517f7616640100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600187141580156107c85750600460006001896107b291906154ad565b8152602001908152602001600020600301548611155b156107ff576040517f4b3d204d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600354871415801561084a57506004600060018961081d9190615479565b8152602001908152602001600020600001546001848861083d9190615479565b61084791906154ad565b10155b15610881576040517f4b3d204d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85600460008981526020019081526020016000206000018190555084866108a89190615479565b60046000898152602001908152602001600020600101819055508385876108cf9190615479565b6108d99190615479565b6004600089815260200190815260200160002060020181905550600183876109019190615479565b61090b91906154ad565b600460008981526020019081526020016000206003018190555050505050505050565b33600660008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166109b2576040517feaa45d6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825182518082146109ef576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8560046000828152602001908152602001600020600101544210158015610a2b5750600460008281526020019081526020016000206002015442105b610a61576040517f4b7a7ea200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b6004600089815260200190815260200160002060060180549050811015610b5c576000600460008a81526020019081526020016000206006018281548110610aaf57610aae6154e1565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600460008b815260200190815260200160002060070160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550508080610b5490615510565b915050610a64565b506000610b67612d46565b905060008651875183610b7a9190615587565b610b8491906155b8565b82610b8f91906154ad565b9050600080600080600460008e815260200190815260200160002060050160019054906101000a900460ff1660ff1667ffffffffffffffff811115610bd757610bd6614345565b5b604051908082528060200260200182016040528015610c055781602001602082028036833780820191505090505b5090505b8a51841015610ec6578a518503610c1f57600094505b600f60008d8781518110610c3657610c356154e1565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16158015610cb85750600460008e815260200190815260200160002060050160019054906101000a900460ff1660ff1683105b8015610ce1575060008b8681518110610cd457610cd36154e1565b5b602002602001015160ff16115b15610de3576001600460008f815260200190815260200160002060070160008e8881518110610d1357610d126154e1565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508b8581518110610d7f57610d7e6154e1565b5b6020026020010151818481518110610d9a57610d996154e1565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508280610ddf90615510565b9350505b8a8581518110610df657610df56154e1565b5b6020026020010151600460008f815260200190815260200160002060090160008e8881518110610e2957610e286154e1565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff021916908360ff1602179055508a8581518110610e9957610e986154e1565b5b602002602001015160ff1682610eaf9190615479565b915084806001019550508380600101945050610c09565b600460008e815260200190815260200160002060050160019054906101000a900460ff1660ff16600460008f815260200190815260200160002060040154610f0e9190615479565b821115610f50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f479061566f565b60405180910390fd5b80600460008f81526020019081526020016000206006019080519060200190610f7a9291906140e9565b507f2d2076d8455ccee841675580c81ac35d8b17f201da64e8866611bd7a40c78cc68d82604051610fac9291906156fe565b60405180910390a150505050505050505050505050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b33600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661106d576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82846110799190615479565b82116110b1576040517f7616640100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8681101561119e57600360008154809291906110cf90615510565b9190505550856004600060035481526020019081526020016000206000018190555084866110fd9190615479565b600460006003548152602001908152602001600020600101819055508385876111269190615479565b6111309190615479565b600460006003548152602001908152602001600020600201819055506001838761115a9190615479565b61116491906154ad565b60046000600354815260200190815260200160002060030181905550828661118c9190615479565b955061119781612e1b565b90506110b4565b50505050505050565b33600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661122b576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600160ff16816080015160ff16141580156112525750600260ff16816080015160ff1614155b15611289576040517fb4fa3fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160ff16816080015160ff161480156112a857506000816040015151115b806112ce5750600260ff16816080015160ff161480156112cd57506000816040015151145b5b15611305576040517fb4fa3fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000836060018181525050826002600086815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002019080519060200190611391929190614173565b506060820151816003015560808201518160040160006101000a81548160ff021916908360ff16021790555060a08201518160040160016101000a81548160ff021916908360ff16021790555090505050505050565b60015481565b33600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611471576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082606001511415806114905750600160ff16826080015160ff1614155b806114a057506000826040015151115b156114d7576040517fb4fa3fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600a60008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002019080519060200190611547929190614173565b506060820151816003015560808201518160040160006101000a81548160ff021916908360ff16021790555060a08201518160040160016101000a81548160ff021916908360ff1602179055509050505050565b6115a36141c0565b6004600083815260200190815260200160002060060180548060200260200160405190810160405280929190818152602001828054801561163957602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116115ef575b50505050508160000181905250600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633dcec1a8836040518263ffffffff1660e01b81526004016116a191906148db565b600060405180830381865afa1580156116be573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906116e791906157da565b8160200181905250919050565b60056020528060005260406000206000915054906101000a900460ff1681565b600f6020528060005260406000206000915054906101000a900460ff1681565b60035481565b60046020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050160009054906101000a900460ff16908060050160019054906101000a900460ff16908060050160029054906101000a900460ff16905088565b6117b16141da565b600260008381526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820180548060200260200160405190810160405280929190818152602001828054801561187e57602002820191906000526020600020905b81548152602001906001019080831161186a575b50505050508152602001600382015481526020016004820160009054906101000a900460ff1660ff1660ff1681526020016004820160019054906101000a900460ff1660ff1660ff16815250509050919050565b6118da612e28565b80600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600281565b60006004600084815260200190815260200160002060090160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900460ff16905092915050565b611999612e28565b6119a36000612ea6565b565b6119ad612e28565b80600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600a8060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060030154908060040160009054906101000a900460ff16908060040160019054906101000a900460ff16905085565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b33600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611b13576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600160ff16816080015160ff1614158015611b3a5750600260ff16816080015160ff1614155b15611b71576040517fb4fa3fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160ff16816080015160ff16148015611b9057506000816040015151115b80611bb65750600260ff16816080015160ff16148015611bb557506000816040015151145b5b15611bed576040517fb4fa3fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016000815480929190611c0090615510565b919050555060008360600181815250508260026000600154815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002019080519060200190611c93929190614173565b506060820151816003015560808201518160040160006101000a81548160ff021916908360ff16021790555060a08201518160040160016101000a81548160ff021916908360ff160217905550905050505050565b611cf0612e28565b80600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b33600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611dcf576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460046000828152602001908152602001600020600001544210158015611e0b5750600460008281526020019081526020016000206001015442105b611e41576040517f4b7a7ea200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84518451808214611e7e576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600460008a81526020019081526020016000209050858160050160016101000a81548160ff021916908360ff160217905550858160050160026101000a81548160ff021916908360ff16021790555060008160050160006101000a81548160ff021916908360ff16021790555060005b88518110156120bd576000898281518110611f0e57611f0d6154e1565b5b602002602001015160ff161480611f435750600154898281518110611f3657611f356154e1565b5b602002602001015160ff16115b15611f7a576040517fa549bb0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600501600081819054906101000a900460ff1680929190611f9b90615823565b91906101000a81548160ff021916908360ff16021790555050888181518110611fc757611fc66154e1565b5b60200260200101518260080160008460050160009054906101000a900460ff1660ff16815260200190815260200160002060000160006101000a81548160ff021916908360ff160217905550878181518110612026576120256154e1565b5b60200260200101518260080160008460050160009054906101000a900460ff1660ff16815260200190815260200160002060000160016101000a81548161ffff021916908361ffff160217905550878181518110612087576120866154e1565b5b602002602001015161ffff168260040160008282546120a69190615479565b925050819055506120b681612e1b565b9050611ef0565b50505050505050505050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6120f7612e28565b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6060600060015467ffffffffffffffff81111561215b5761215a614345565b5b60405190808252806020026020018201604052801561219457816020015b6121816141da565b8152602001906001900390816121795790505b5090506000600190505b60015481116122fe57600260008281526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820180548060200260200160405190810160405280929190818152602001828054801561227457602002820191906000526020600020905b815481526020019060010190808311612260575b50505050508152602001600382015481526020016004820160009054906101000a900460ff1660ff1660ff1681526020016004820160019054906101000a900460ff1660ff1660ff1681525050826001836122cf91906154ad565b815181106122e0576122df6154e1565b5b602002602001018190525080806122f690615510565b91505061219e565b508091505090565b600181565b600080339050803b91503273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612383576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237a90615898565b60405180910390fd5b600082146123c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123bd90615904565b60405180910390fd5b6123ce612f6a565b6004600086815260200190815260200160002060020154421015801561240a575060046000868152602001908152602001600020600301544211155b612440576040517f5f8cf72a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663eae07d9d87600460008a815260200190815260200160002060090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900460ff163389896040518663ffffffff1660e01b81526004016125089594939291906159a2565b6020604051808303816000875af1158015612527573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254b9190615a05565b905080612584576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006004600088815260200190815260200160002060090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1660ff1603612624576040517fb19a9f8200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004600087815260200190815260200160002060090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1660ff166004600088815260200190815260200160002060090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900460ff1660ff1603612729576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006004600088815260200190815260200160002060090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900460ff1660ff16036127a5576127a086612fb9565b6127af565b6127ae86613682565b5b506127b8613e3f565b5050505050565b33600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612843576040517f7bfa4b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82518251808214612880576040517f947d5a8400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b84518110156129275784818151811061289f5761289e6154e1565b5b6020026020010151600f60008884815181106128be576128bd6154e1565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061292081612e1b565b9050612883565b505050505050565b33600660008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166129b3576040517feaa45d6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600460008281526020019081526020016000206001015442101580156129ef5750600460008281526020019081526020016000206002015442105b612a25576040517f4b7a7ea200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d046577d846040518263ffffffff1660e01b8152600401612a8091906148db565b6020604051808303816000875af1158015612a9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac39190615a32565b50505050565b606060006004600084815260200190815260200160002060050160009054906101000a900460ff1660ff1667ffffffffffffffff811115612b0d57612b0c614345565b5b604051908082528060200260200182016040528015612b4657816020015b612b3361422c565b815260200190600190039081612b2b5790505b5090506000600190505b6004600085815260200190815260200160002060050160009054906101000a900460ff1660ff168111612c29576004600085815260200190815260200160002060080160008281526020019081526020016000206040518060400160405290816000820160009054906101000a900460ff1660ff1660ff1681526020016000820160019054906101000a900461ffff1661ffff1661ffff168152505082600183612bfa91906154ad565b81518110612c0b57612c0a6154e1565b5b60200260200101819052508080612c2190615510565b915050612b50565b5080915050919050565b60026020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060030154908060040160009054906101000a900460ff16908060040160019054906101000a900460ff16905085565b612cab612e28565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612d1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d1190615ad1565b60405180910390fd5b612d2381612ea6565b50565b60066020528060005260406000206000915054906101000a900460ff1681565b600080434233604051602001612d5c9190615b39565b6040516020818303038152906040528051906020012060001c612d7f9190615587565b454241604051602001612d929190615b8f565b6040516020818303038152906040528051906020012060001c612db59190615587565b4442612dc19190615479565b612dcb9190615479565b612dd59190615479565b612ddf9190615479565b612de99190615479565b604051602001612df99190615bcb565b6040516020818303038152906040528051906020012060001c90508091505090565b6000600182019050919050565b612e30613e49565b73ffffffffffffffffffffffffffffffffffffffff16612e4e611a66565b73ffffffffffffffffffffffffffffffffffffffff1614612ea4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9b90615c32565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600260085403612faf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fa690615c9e565b60405180910390fd5b6002600881905550565b60006004600083815260200190815260200160002090508060070160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156132ab576001600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060008160070160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508060090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001600181819054906101000a900460ff168092919060010191906101000a81548160ff021916908360ff1602179055505080600501600281819054906101000a900460ff16809291906001900391906101000a81548160ff021916908360ff16021790555050600a600301600081548092919060010191905055506132a682600a6040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820180548060200260200160405190810160405280929190818152602001828054801561325457602002820191906000526020600020905b815481526020019060010190808311613240575b50505050508152602001600382015481526020016004820160009054906101000a900460ff1660ff1660ff1681526020016004820160019054906101000a900460ff1660ff1660ff1681525050613e51565b61367e565b60006132b5612d46565b90506000600183600401548460040154846132d09190615587565b6132da91906155b8565b836132e591906154ad565b6132ef9190615479565b90506000806000600190505b8560050160009054906101000a900460ff1660ff16811161339857600086600801600083815260200190815260200160002060000160019054906101000a900461ffff1661ffff1603156133885785600801600082815260200190815260200160002060000160019054906101000a900461ffff16820191508161ffff16841161338757809250613398565b5b61339181612e1b565b90506132fb565b50600085600801600084815260200190815260200160002060000160009054906101000a900460ff1660ff16905060018660090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006002600085815260200190815260200160002060040160019054906101000a900460ff1660ff16815260200190815260200160002060006101000a81548160ff021916908315150217905550856008016000848152602001908152602001600020600001600181819054906101000a900461ffff16809291906001900391906101000a81548161ffff021916908361ffff160217905550508560090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001600181819054906101000a900460ff168092919060010191906101000a81548160ff021916908360ff16021790555050856004016000815480929190600190039190505550600260008281526020019081526020016000206003016000815480929190600101919050555061367887600260008481526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820180548060200260200160405190810160405280929190818152602001828054801561362657602002820191906000526020600020905b815481526020019060010190808311613612575b50505050508152602001600382015481526020016004820160009054906101000a900460ff1660ff1660ff1681526020016004820160019054906101000a900460ff1660ff1660ff1681525050613e51565b50505050505b5050565b60006004600083815260200190815260200160002090506000806000600190505b8360050160009054906101000a900460ff1660ff1681116137e65760006002600086600801600085815260200190815260200160002060000160009054906101000a900460ff1660ff16815260200190815260200160002060040160019054906101000a900460ff1660ff1690508460090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600082815260200190815260200160002060009054906101000a900460ff16156137a95784600801600083815260200190815260200160002060000160019054906101000a900461ffff16830192506137d5565b84600801600083815260200190815260200160002060000160019054906101000a900461ffff16840193505b506137df81612e1b565b90506136a3565b5060006137f1612d46565b905060008085600401548461ffff16036139b057600060018561ffff168661ffff168661381e9190615587565b61382891906155b8565b8561383391906154ad565b61383d9190615479565b90506000600190505b8760050160009054906101000a900460ff1660ff1681116139a9576000600260008a600801600085815260200190815260200160002060000160009054906101000a900460ff1660ff16815260200190815260200160002060040160019054906101000a900460ff1660ff169050600089600801600084815260200190815260200160002060000160019054906101000a900461ffff1661ffff16148061394d57508860090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600082815260200190815260200160002060009054906101000a900460ff16155b156139585750613999565b88600801600083815260200190815260200160002060000160019054906101000a900461ffff1661ffff168401935083831161399757819450506139a9565b505b6139a281612e1b565b9050613846565b5050613b56565b600060018661ffff168761ffff16866139c99190615587565b6139d391906155b8565b856139de91906154ad565b6139e89190615479565b90506000600190505b8760050160009054906101000a900460ff1660ff168111613b53576000600260008a600801600085815260200190815260200160002060000160009054906101000a900460ff1660ff16815260200190815260200160002060040160019054906101000a900460ff1660ff169050600089600801600084815260200190815260200160002060000160019054906101000a900461ffff1661ffff161480613af757508860090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101600082815260200190815260200160002060009054906101000a900460ff165b15613b025750613b43565b88600801600083815260200190815260200160002060000160019054906101000a900461ffff1661ffff1684019350838311613b415781945050613b53565b505b613b4c81612e1b565b90506139f1565b50505b600086600801600084815260200190815260200160002060000160009054906101000a900460ff1660ff16905060018760090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006002600085815260200190815260200160002060040160019054906101000a900460ff1660ff16815260200190815260200160002060006101000a81548160ff021916908315150217905550866008016000848152602001908152602001600020600001600181819054906101000a900461ffff16809291906001900391906101000a81548161ffff021916908361ffff160217905550508660090160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001600181819054906101000a900460ff168092919060010191906101000a81548160ff021916908360ff160217905550508660040160008154809291906001900391905055506002600082815260200190815260200160002060030160008154809291906001019190505550613e3588600260008481526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820154815260200160028201805480602002602001604051908101604052809291908181526020018280548015613de357602002820191906000526020600020905b815481526020019060010190808311613dcf575b50505050508152602001600382015481526020016004820160009054906101000a900460ff1660ff1660ff1681526020016004820160019054906101000a900460ff1660ff1660ff1681525050613e51565b5050505050505050565b6001600881905550565b600033905090565b600160ff16816080015160ff1603613f51576000816000015190508073ffffffffffffffffffffffffffffffffffffffff1663f242432a600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633856020015160016040518563ffffffff1660e01b8152600401613ed29493929190615d1f565b600060405180830381600087803b158015613eec57600080fd5b505af1158015613f00573d6000803e3d6000fd5b505050507f7a9968751a59a2a8b2b71d8cca320739a4d92097045da1ce8cdd5478e2fcd7138333846000015185602001518660800151604051613f47959493929190615d77565b60405180910390a1505b600260ff16816080015160ff16036140e55760008160000151905081606001518260400151511015613faf576040517f675cae3800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166323b872dd600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff163385604001516001876060015161400591906154ad565b81518110614016576140156154e1565b5b60200260200101516040518463ffffffff1660e01b815260040161403c93929190615dca565b600060405180830381600087803b15801561405657600080fd5b505af115801561406a573d6000803e3d6000fd5b505050507f7a9968751a59a2a8b2b71d8cca320739a4d92097045da1ce8cdd5478e2fcd713833384600001518560400151600187606001516140ac91906154ad565b815181106140bd576140bc6154e1565b5b602002602001015186608001516040516140db959493929190615d77565b60405180910390a1505b5050565b828054828255906000526020600020908101928215614162579160200282015b828111156141615782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190614109565b5b50905061416f919061424d565b5090565b8280548282559060005260206000209081019282156141af579160200282015b828111156141ae578251825591602001919060010190614193565b5b5090506141bc919061424d565b5090565b604051806040016040528060608152602001606081525090565b6040518060c00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081526020016060815260200160008152602001600060ff168152602001600060ff1681525090565b6040518060400160405280600060ff168152602001600061ffff1681525090565b5b8082111561426657600081600090555060010161424e565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6142918161427e565b811461429c57600080fd5b50565b6000813590506142ae81614288565b92915050565b600080600080600060a086880312156142d0576142cf614274565b5b60006142de8882890161429f565b95505060206142ef8882890161429f565b94505060406143008882890161429f565b93505060606143118882890161429f565b92505060806143228882890161429f565b9150509295509295909350565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61437d82614334565b810181811067ffffffffffffffff8211171561439c5761439b614345565b5b80604052505050565b60006143af61426a565b90506143bb8282614374565b919050565b600067ffffffffffffffff8211156143db576143da614345565b5b602082029050602081019050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061441c826143f1565b9050919050565b61442c81614411565b811461443757600080fd5b50565b60008135905061444981614423565b92915050565b600061446261445d846143c0565b6143a5565b90508083825260208201905060208402830185811115614485576144846143ec565b5b835b818110156144ae578061449a888261443a565b845260208401935050602081019050614487565b5050509392505050565b600082601f8301126144cd576144cc61432f565b5b81356144dd84826020860161444f565b91505092915050565b600067ffffffffffffffff82111561450157614500614345565b5b602082029050602081019050919050565b600060ff82169050919050565b61452881614512565b811461453357600080fd5b50565b6000813590506145458161451f565b92915050565b600061455e614559846144e6565b6143a5565b90508083825260208201905060208402830185811115614581576145806143ec565b5b835b818110156145aa57806145968882614536565b845260208401935050602081019050614583565b5050509392505050565b600082601f8301126145c9576145c861432f565b5b81356145d984826020860161454b565b91505092915050565b6000806000606084860312156145fb576145fa614274565b5b60006146098682870161429f565b935050602084013567ffffffffffffffff81111561462a57614629614279565b5b614636868287016144b8565b925050604084013567ffffffffffffffff81111561465757614656614279565b5b614663868287016145b4565b9150509250925092565b6000819050919050565b600061469261468d614688846143f1565b61466d565b6143f1565b9050919050565b60006146a482614677565b9050919050565b60006146b682614699565b9050919050565b6146c6816146ab565b82525050565b60006020820190506146e160008301846146bd565b92915050565b600080fd5b600080fd5b600067ffffffffffffffff82111561470c5761470b614345565b5b602082029050602081019050919050565b600061473061472b846146f1565b6143a5565b90508083825260208201905060208402830185811115614753576147526143ec565b5b835b8181101561477c5780614768888261429f565b845260208401935050602081019050614755565b5050509392505050565b600082601f83011261479b5761479a61432f565b5b81356147ab84826020860161471d565b91505092915050565b600060c082840312156147ca576147c96146e7565b5b6147d460c06143a5565b905060006147e48482850161443a565b60008301525060206147f88482850161429f565b602083015250604082013567ffffffffffffffff81111561481c5761481b6146ec565b5b61482884828501614786565b604083015250606061483c8482850161429f565b606083015250608061485084828501614536565b60808301525060a061486484828501614536565b60a08301525092915050565b6000806040838503121561488757614886614274565b5b60006148958582860161429f565b925050602083013567ffffffffffffffff8111156148b6576148b5614279565b5b6148c2858286016147b4565b9150509250929050565b6148d58161427e565b82525050565b60006020820190506148f060008301846148cc565b92915050565b60006020828403121561490c5761490b614274565b5b600082013567ffffffffffffffff81111561492a57614929614279565b5b614936848285016147b4565b91505092915050565b60006020828403121561495557614954614274565b5b60006149638482850161429f565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6149a181614411565b82525050565b60006149b38383614998565b60208301905092915050565b6000602082019050919050565b60006149d78261496c565b6149e18185614977565b93506149ec83614988565b8060005b83811015614a1d578151614a0488826149a7565b9750614a0f836149bf565b9250506001810190506149f0565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b614a5f8161427e565b82525050565b6000614a718383614a56565b60208301905092915050565b6000602082019050919050565b6000614a9582614a2a565b614a9f8185614a35565b9350614aaa83614a46565b8060005b83811015614adb578151614ac28882614a65565b9750614acd83614a7d565b925050600181019050614aae565b5085935050505092915050565b60006040830160008301518482036000860152614b0582826149cc565b91505060208301518482036020860152614b1f8282614a8a565b9150508091505092915050565b60006020820190508181036000830152614b468184614ae8565b905092915050565b600060208284031215614b6457614b63614274565b5b6000614b728482850161443a565b91505092915050565b60008115159050919050565b614b9081614b7b565b82525050565b6000602082019050614bab6000830184614b87565b92915050565b614bba81614512565b82525050565b600061010082019050614bd6600083018b6148cc565b614be3602083018a6148cc565b614bf060408301896148cc565b614bfd60608301886148cc565b614c0a60808301876148cc565b614c1760a0830186614bb1565b614c2460c0830185614bb1565b614c3160e0830184614bb1565b9998505050505050505050565b614c4781614512565b82525050565b600060c083016000830151614c656000860182614998565b506020830151614c786020860182614a56565b5060408301518482036040860152614c908282614a8a565b9150506060830151614ca56060860182614a56565b506080830151614cb86080860182614c3e565b5060a0830151614ccb60a0860182614c3e565b508091505092915050565b60006020820190508181036000830152614cf08184614c4d565b905092915050565b6000602082019050614d0d6000830184614bb1565b92915050565b60008060408385031215614d2a57614d29614274565b5b6000614d388582860161429f565b9250506020614d498582860161443a565b9150509250929050565b614d5c81614b7b565b8114614d6757600080fd5b50565b600081359050614d7981614d53565b92915050565b60008060408385031215614d9657614d95614274565b5b6000614da48582860161443a565b9250506020614db585828601614d6a565b9150509250929050565b614dc881614411565b82525050565b600060a082019050614de36000830188614dbf565b614df060208301876148cc565b614dfd60408301866148cc565b614e0a6060830185614bb1565b614e176080830184614bb1565b9695505050505050565b6000602082019050614e366000830184614dbf565b92915050565b600067ffffffffffffffff821115614e5757614e56614345565b5b602082029050602081019050919050565b600061ffff82169050919050565b614e7f81614e68565b8114614e8a57600080fd5b50565b600081359050614e9c81614e76565b92915050565b6000614eb5614eb084614e3c565b6143a5565b90508083825260208201905060208402830185811115614ed857614ed76143ec565b5b835b81811015614f015780614eed8882614e8d565b845260208401935050602081019050614eda565b5050509392505050565b600082601f830112614f2057614f1f61432f565b5b8135614f30848260208601614ea2565b91505092915050565b60008060008060808587031215614f5357614f52614274565b5b6000614f618782880161429f565b945050602085013567ffffffffffffffff811115614f8257614f81614279565b5b614f8e878288016145b4565b935050604085013567ffffffffffffffff811115614faf57614fae614279565b5b614fbb87828801614f0b565b9250506060614fcc87828801614536565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600060c08301600083015161501c6000860182614998565b50602083015161502f6020860182614a56565b50604083015184820360408601526150478282614a8a565b915050606083015161505c6060860182614a56565b50608083015161506f6080860182614c3e565b5060a083015161508260a0860182614c3e565b508091505092915050565b60006150998383615004565b905092915050565b6000602082019050919050565b60006150b982614fd8565b6150c38185614fe3565b9350836020820285016150d585614ff4565b8060005b8581101561511157848403895281516150f2858261508d565b94506150fd836150a1565b925060208a019950506001810190506150d9565b50829750879550505050505092915050565b6000602082019050818103600083015261513d81846150ae565b905092915050565b600080fd5b60008083601f8401126151605761515f61432f565b5b8235905067ffffffffffffffff81111561517d5761517c615145565b5b602083019150836001820283011115615199576151986143ec565b5b9250929050565b6000806000604084860312156151b9576151b8614274565b5b60006151c78682870161429f565b935050602084013567ffffffffffffffff8111156151e8576151e7614279565b5b6151f48682870161514a565b92509250509250925092565b600067ffffffffffffffff82111561521b5761521a614345565b5b602082029050602081019050919050565b600061523f61523a84615200565b6143a5565b90508083825260208201905060208402830185811115615262576152616143ec565b5b835b8181101561528b57806152778882614d6a565b845260208401935050602081019050615264565b5050509392505050565b600082601f8301126152aa576152a961432f565b5b81356152ba84826020860161522c565b91505092915050565b600080604083850312156152da576152d9614274565b5b600083013567ffffffffffffffff8111156152f8576152f7614279565b5b615304858286016144b8565b925050602083013567ffffffffffffffff81111561532557615324614279565b5b61533185828601615295565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61537081614e68565b82525050565b60408201600082015161538c6000850182614c3e565b50602082015161539f6020850182615367565b50505050565b60006153b18383615376565b60408301905092915050565b6000602082019050919050565b60006153d58261533b565b6153df8185615346565b93506153ea83615357565b8060005b8381101561541b57815161540288826153a5565b975061540d836153bd565b9250506001810190506153ee565b5085935050505092915050565b6000602082019050818103600083015261544281846153ca565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006154848261427e565b915061548f8361427e565b92508282019050808211156154a7576154a661544a565b5b92915050565b60006154b88261427e565b91506154c38361427e565b92508282039050818111156154db576154da61544a565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061551b8261427e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361554d5761554c61544a565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006155928261427e565b915061559d8361427e565b9250826155ad576155ac615558565b5b828204905092915050565b60006155c38261427e565b91506155ce8361427e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156156075761560661544a565b5b828202905092915050565b600082825260208201905092915050565b7f496e76616c696420547265617375726520416d6f756e74000000000000000000600082015250565b6000615659601783615612565b915061566482615623565b602082019050919050565b600060208201905081810360008301526156888161564c565b9050919050565b600082825260208201905092915050565b60006156ab8261496c565b6156b5818561568f565b93506156c083614988565b8060005b838110156156f15781516156d888826149a7565b97506156e3836149bf565b9250506001810190506156c4565b5085935050505092915050565b600060408201905061571360008301856148cc565b818103602083015261572581846156a0565b90509392505050565b60008151905061573d81614288565b92915050565b6000615756615751846146f1565b6143a5565b90508083825260208201905060208402830185811115615779576157786143ec565b5b835b818110156157a2578061578e888261572e565b84526020840193505060208101905061577b565b5050509392505050565b600082601f8301126157c1576157c061432f565b5b81516157d1848260208601615743565b91505092915050565b6000602082840312156157f0576157ef614274565b5b600082015167ffffffffffffffff81111561580e5761580d614279565b5b61581a848285016157ac565b91505092915050565b600061582e82614512565b915060ff82036158415761584061544a565b5b600182019050919050565b7f74782e6f726967696e20213d206d73672e73656e646572000000000000000000600082015250565b6000615882601783615612565b915061588d8261584c565b602082019050919050565b600060208201905081810360008301526158b181615875565b9050919050565b7f436f6e74726163742063616c6c7320617265206e6f7420616c6c6f7765640000600082015250565b60006158ee601e83615612565b91506158f9826158b8565b602082019050919050565b6000602082019050818103600083015261591d816158e1565b9050919050565b600061593f61593a61593584614512565b61466d565b61427e565b9050919050565b61594f81615924565b82525050565b600082825260208201905092915050565b82818337600083830152505050565b60006159818385615955565b935061598e838584615966565b61599783614334565b840190509392505050565b60006080820190506159b760008301886148cc565b6159c46020830187615946565b6159d16040830186614dbf565b81810360608301526159e4818486615975565b90509695505050505050565b6000815190506159ff81614d53565b92915050565b600060208284031215615a1b57615a1a614274565b5b6000615a29848285016159f0565b91505092915050565b600060208284031215615a4857615a47614274565b5b6000615a568482850161572e565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000615abb602683615612565b9150615ac682615a5f565b604082019050919050565b60006020820190508181036000830152615aea81615aae565b9050919050565b60008160601b9050919050565b6000615b0982615af1565b9050919050565b6000615b1b82615afe565b9050919050565b615b33615b2e82614411565b615b10565b82525050565b6000615b458284615b22565b60148201915081905092915050565b6000615b5f826143f1565b9050919050565b6000615b7182615afe565b9050919050565b615b89615b8482615b54565b615b66565b82525050565b6000615b9b8284615b78565b60148201915081905092915050565b6000819050919050565b615bc5615bc08261427e565b615baa565b82525050565b6000615bd78284615bb4565b60208201915081905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000615c1c602083615612565b9150615c2782615be6565b602082019050919050565b60006020820190508181036000830152615c4b81615c0f565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000615c88601f83615612565b9150615c9382615c52565b602082019050919050565b60006020820190508181036000830152615cb781615c7b565b9050919050565b6000819050919050565b6000615ce3615cde615cd984615cbe565b61466d565b61427e565b9050919050565b615cf381615cc8565b82525050565b50565b6000615d09600083615955565b9150615d1482615cf9565b600082019050919050565b600060a082019050615d346000830187614dbf565b615d416020830186614dbf565b615d4e60408301856148cc565b615d5b6060830184615cea565b8181036080830152615d6c81615cfc565b905095945050505050565b600060a082019050615d8c60008301886148cc565b615d996020830187614dbf565b615da66040830186614dbf565b615db360608301856148cc565b615dc06080830184615946565b9695505050505050565b6000606082019050615ddf6000830186614dbf565b615dec6020830185614dbf565b615df960408301846148cc565b94935050505056fea264697066735822122056b215dafb4a6e469bd247e592121a6d3ae35354ebae9eceecbafd65591552cf64736f6c63430008100033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000df2d64b5440bf2b4bcc1074ec0e05d6463a9b5c

-----Decoded View---------------
Arg [0] : _pxChainlinkContractAddress (address): 0x0dF2D64B5440Bf2B4bCc1074ec0E05d6463A9b5C

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000df2d64b5440bf2b4bcc1074ec0e05d6463a9b5c


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.