MON Price: $0.021369 (-3.60%)

Contract

0x26A56f3245161CE7938200F1366A1cf9549c7e20

Overview

MON Balance

Monad Chain LogoMonad Chain LogoMonad Chain Logo0.002999999999999997 MON

MON Value

Less Than $0.01 (@ $0.02/MON)

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Treasury Transfe...415882792025-12-12 16:40:1846 days ago1765557618IN
0x26A56f32...9549c7e20
0 MON0.00646092103.88
Claim Reward415825212025-12-12 16:01:4646 days ago1765555306IN
0x26A56f32...9549c7e20
0 MON0.01185664101.94
Finalize Raffle415824302025-12-12 16:01:0946 days ago1765555269IN
0x26A56f32...9549c7e20
0 MON0.03951123101.94
Treasury Transfe...415811652025-12-12 15:52:4146 days ago1765554761IN
0x26A56f32...9549c7e20
0 MON0.01068784121.728
Join Raffle415798792025-12-12 15:44:0346 days ago1765554243IN
0x26A56f32...9549c7e20
1 MON0.0196049100
Create Raffle415796412025-12-12 15:42:2746 days ago1765554147IN
0x26A56f32...9549c7e20
0 MON0.02732322101.9885
Claim Reward408516272025-12-09 6:23:3550 days ago1765261415IN
0x26A56f32...9549c7e20
0 MON0.01185664101.94
Finalize Raffle408515792025-12-09 6:23:1650 days ago1765261396IN
0x26A56f32...9549c7e20
0 MON0.0387593100
Join Raffle408512262025-12-09 6:20:5450 days ago1765261254IN
0x26A56f32...9549c7e20
1 MON0.02534384129.27299785
Create Raffle408510742025-12-09 6:19:5350 days ago1765261193IN
0x26A56f32...9549c7e20
0 MON0.0267905100
Treasury Transfe...407116342025-12-08 14:44:3351 days ago1765205073IN
0x26A56f32...9549c7e20
0 MON0.00640179102.9294
Claim Reward406902782025-12-08 12:21:2151 days ago1765196481IN
0x26A56f32...9549c7e20
0 MON0.01774677152.58169438
Finalize Raffle406902172025-12-08 12:20:5651 days ago1765196456IN
0x26A56f32...9549c7e20
0 MON0.03953378101.9982
Join Raffle406897592025-12-08 12:17:5251 days ago1765196272IN
0x26A56f32...9549c7e20
1 MON0.0201792102.9294
Create Raffle406895342025-12-08 12:16:2151 days ago1765196181IN
0x26A56f32...9549c7e20
0 MON0.02731023101.94
Create Raffle406893332025-12-08 12:15:0051 days ago1765196100IN
0x26A56f32...9549c7e20
0 MON0.02731023101.94
Finalize Raffle406892002025-12-08 12:14:0651 days ago1765196046IN
0x26A56f32...9549c7e20
0 MON0.01185149102.9294
Create Raffle406888822025-12-08 12:11:5651 days ago1765195916IN
0x26A56f32...9549c7e20
0 MON0.02731023101.94
Claim Refund406886542025-12-08 12:10:2351 days ago1765195823IN
0x26A56f32...9549c7e20
0 MON0.0169056100
Finalize Raffle406885742025-12-08 12:09:5151 days ago1765195791IN
0x26A56f32...9549c7e20
0 MON0.0101833100
Join Raffle406883782025-12-08 12:08:2951 days ago1765195709IN
0x26A56f32...9549c7e20
1 MON0.01998523101.94
Create Raffle406881422025-12-08 12:06:5351 days ago1765195613IN
0x26A56f32...9549c7e20
0 MON0.02731023101.94
Transfer406872952025-12-08 12:01:1151 days ago1765195271IN
0x26A56f32...9549c7e20
10 MON0.0022964100

Latest 10 internal transactions

Advanced mode:
Parent Transaction Hash Block From To
415882792025-12-12 16:40:1846 days ago1765557618
0x26A56f32...9549c7e20
2.46 MON
415825212025-12-12 16:01:4646 days ago1765555306
0x26A56f32...9549c7e20
1 MON
415824302025-12-12 16:01:0946 days ago1765555269
0x26A56f32...9549c7e20
0.737 MON
415811652025-12-12 15:52:4146 days ago1765554761
0x26A56f32...9549c7e20
1 MON
408516272025-12-09 6:23:3550 days ago1765261415
0x26A56f32...9549c7e20
1 MON
408515792025-12-09 6:23:1650 days ago1765261396
0x26A56f32...9549c7e20
0.4 MON
407116342025-12-08 14:44:3351 days ago1765205073
0x26A56f32...9549c7e20
5 MON
406902782025-12-08 12:21:2151 days ago1765196481
0x26A56f32...9549c7e20
1 MON
406902172025-12-08 12:20:5651 days ago1765196456
0x26A56f32...9549c7e20
0.4 MON
406886542025-12-08 12:10:2351 days ago1765195823
0x26A56f32...9549c7e20
1 MON
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
OneMON

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
No with 200 runs

Other Settings:
paris EvmVersion
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@pythnetwork/entropy-sdk-solidity/IEntropy.sol";
import "@pythnetwork/entropy-sdk-solidity/IEntropyConsumer.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

contract OneMON is IEntropyConsumer, ReentrancyGuard {

    // ═══════════════════════════════════════════════════════════
    //                       CONSTANTS
    // ═══════════════════════════════════════════════════════════

    address public constant ADMIN = 0x14d5aa304Af9c1aeFf1F37375f85bA0cbFb6C104;
    address public constant TREASURY = 0x6779387e262e3eC8C81F62DCD3B2348931B5254d;
    IEntropy public constant PYTH_ENTROPY = IEntropy(0xD458261E832415CFd3BAE5E416FdF3230ce6F134);

    uint256 public constant ENTRY_FEE = 1 ether;
    uint256 public constant CLAIM_WINDOW = 3 days;
    uint256 public constant VRF_TIMEOUT = 1 days;

    // ═══════════════════════════════════════════════════════════
    //                        ENUMS
    // ═══════════════════════════════════════════════════════════

    enum RaffleState {
        Created,
        Active,
        PendingVRF,
        WinnerSelected,
        RefundsEnabled,
        Completed,
        Cancelled
    }

    // ═══════════════════════════════════════════════════════════
    //                       STRUCTS
    // ═══════════════════════════════════════════════════════════

    struct Raffle {
        uint256 startTime;
        uint256 endTime;
        uint256 threshold;
        uint256 rewardAmount;
        uint256 participantCount;
        address winner;
        bool rewardClaimed;
        uint256 claimDeadline;
        uint256 refundsClaimedCount;
        uint256 vrfRequestTime;
        RaffleState state;
    }

    // ═══════════════════════════════════════════════════════════
    //                       STORAGE
    // ═══════════════════════════════════════════════════════════

    uint256 public nextRaffleId = 1;
    mapping(uint256 => Raffle) public raffles;
    mapping(uint256 => address[]) public raffleParticipants;
    mapping(uint256 => mapping(address => bool)) public hasJoined;
    mapping(uint256 => mapping(address => bool)) public hasClaimedRefund;
    mapping(uint64 => uint256) public vrfRequestToRaffle;

    uint256[] public activeRaffleIds;
    mapping(uint256 => uint256) public raffleIdToActiveIndex;

    // ═══════════════════════════════════════════════════════════
    //                       EVENTS
    // ═══════════════════════════════════════════════════════════

    event RaffleCreated(uint256 indexed raffleId, uint256 startTime, uint256 endTime, uint256 threshold, uint256 rewardAmount);
    event ParticipantJoined(uint256 indexed raffleId, address indexed participant, uint256 participantCount);
    event RandomnessRequested(uint256 indexed raffleId, uint64 sequenceNumber);
    event WinnerSelected(uint256 indexed raffleId, address indexed winner, uint256 rewardAmount);
    event RewardClaimed(uint256 indexed raffleId, address indexed winner, uint256 amount);
    event RefundsEnabled(uint256 indexed raffleId, uint256 claimDeadline);
    event RefundClaimed(uint256 indexed raffleId, address indexed participant);
    event TreasuryTransfer(uint256 amount);
    event RaffleCompleted(uint256 indexed raffleId);
    event RaffleCancelled(uint256 indexed raffleId, string reason);
    event GasInjected(address indexed sender, uint256 amount);

    // ═══════════════════════════════════════════════════════════
    //                      MODIFIERS
    // ═══════════════════════════════════════════════════════════

    modifier onlyAdmin() {
        require(msg.sender == ADMIN, "Not admin");
        _;
    }

    // ═══════════════════════════════════════════════════════════
    //                  ADMIN FUNCTIONS
    // ═══════════════════════════════════════════════════════════

    function createRaffle(
        uint256 startTime,
        uint256 endTime,
        uint256 threshold,
        uint256 rewardAmount
    ) external onlyAdmin {
        require(startTime < endTime, "Invalid time range");
        require(startTime > block.timestamp, "Start time must be future");
        require(threshold > 0, "Threshold must be > 0");
        require(rewardAmount > 0, "Reward must be > 0");
        require(address(this).balance >= rewardAmount + getReservedFunds(), "Insufficient balance");

        uint256 raffleId = nextRaffleId++;

        raffles[raffleId] = Raffle({
            startTime: startTime,
            endTime: endTime,
            threshold: threshold,
            rewardAmount: rewardAmount,
            participantCount: 0,
            winner: address(0),
            rewardClaimed: false,
            claimDeadline: 0,
            refundsClaimedCount: 0,
            vrfRequestTime: 0,
            state: RaffleState.Created
        });

        activeRaffleIds.push(raffleId);
        raffleIdToActiveIndex[raffleId] = activeRaffleIds.length - 1;

        emit RaffleCreated(raffleId, startTime, endTime, threshold, rewardAmount);
    }

    function finalizeRaffle(uint256 raffleId) external onlyAdmin nonReentrant {
        Raffle storage raffle = raffles[raffleId];

        require(raffle.state == RaffleState.Active || raffle.state == RaffleState.Created, "Invalid state");
        require(block.timestamp > raffle.endTime, "Raffle not ended");

        if (raffle.participantCount == 0) {
            raffle.state = RaffleState.Completed;
            _removeFromActiveRaffles(raffleId);
            emit RaffleCancelled(raffleId, "No participants");
            emit RaffleCompleted(raffleId);
        } else if (raffle.participantCount >= raffle.threshold) {
            _requestRandomness(raffleId);
        } else {
            _enableRefunds(raffleId);
        }
    }

    function cancelStuckRaffle(uint256 raffleId) external onlyAdmin nonReentrant {
        Raffle storage raffle = raffles[raffleId];

        require(raffle.state == RaffleState.PendingVRF, "Not pending VRF");
        require(block.timestamp > raffle.vrfRequestTime + VRF_TIMEOUT, "VRF timeout not reached");

        raffle.state = RaffleState.Cancelled;
        raffle.claimDeadline = block.timestamp + CLAIM_WINDOW;

        emit RaffleCancelled(raffleId, "VRF timeout");
    }

    function markRaffleCompleted(uint256 raffleId) external onlyAdmin {
        Raffle storage raffle = raffles[raffleId];

        bool isExpiredWinner = raffle.state == RaffleState.WinnerSelected && 
                               block.timestamp > raffle.claimDeadline;

        bool isExpiredRefunds = raffle.state == RaffleState.RefundsEnabled && 
                                block.timestamp > raffle.claimDeadline;

        bool isExpiredCancelled = raffle.state == RaffleState.Cancelled && 
                                  block.timestamp > raffle.claimDeadline;

        require(isExpiredWinner || isExpiredRefunds || isExpiredCancelled, "Cannot mark completed");

        raffle.state = RaffleState.Completed;
        _removeFromActiveRaffles(raffleId);

        emit RaffleCompleted(raffleId);
    }

    function injectGas() external payable onlyAdmin {
        require(msg.value > 0, "Must send MON");
        emit GasInjected(msg.sender, msg.value);
    }

    function treasuryTransfer(uint256 amount) external onlyAdmin nonReentrant {
        require(amount > 0, "Amount must be > 0");
        uint256 reserved = getReservedFunds();
        uint256 withdrawable = address(this).balance - reserved;
        require(amount <= withdrawable, "Exceeds withdrawable amount");

        (bool success, ) = payable(TREASURY).call{value: amount}("");
        require(success, "Transfer failed");

        emit TreasuryTransfer(amount);
    }

    // ═══════════════════════════════════════════════════════════
    //                  USER FUNCTIONS
    // ═══════════════════════════════════════════════════════════

    function joinRaffle(uint256 raffleId) external payable nonReentrant {
        Raffle storage raffle = raffles[raffleId];

        require(raffle.state == RaffleState.Created || raffle.state == RaffleState.Active, "Raffle not open");
        require(block.timestamp >= raffle.startTime, "Raffle not started");
        require(block.timestamp < raffle.endTime, "Raffle ended");
        require(msg.value == ENTRY_FEE, "Must send exactly 1 MON");
        require(!hasJoined[raffleId][msg.sender], "Already joined");

        if (raffle.state == RaffleState.Created) {
            raffle.state = RaffleState.Active;
        }

        hasJoined[raffleId][msg.sender] = true;
        raffleParticipants[raffleId].push(msg.sender);
        raffle.participantCount++;

        emit ParticipantJoined(raffleId, msg.sender, raffle.participantCount);
    }

    function claimReward(uint256 raffleId) external nonReentrant {
        Raffle storage raffle = raffles[raffleId];

        require(raffle.state == RaffleState.WinnerSelected, "Winner not selected");
        require(msg.sender == raffle.winner, "Not the winner");
        require(!raffle.rewardClaimed, "Already claimed");
        require(block.timestamp <= raffle.claimDeadline, "Claim window expired");

        raffle.rewardClaimed = true;
        raffle.state = RaffleState.Completed;
        _removeFromActiveRaffles(raffleId);

        (bool success, ) = payable(msg.sender).call{value: raffle.rewardAmount}("");
        require(success, "Transfer failed");

        emit RewardClaimed(raffleId, msg.sender, raffle.rewardAmount);
        emit RaffleCompleted(raffleId);
    }

    function claimRefund(uint256 raffleId) external nonReentrant {
        Raffle storage raffle = raffles[raffleId];

        require(
            raffle.state == RaffleState.RefundsEnabled || raffle.state == RaffleState.Cancelled,
            "Refunds not enabled"
        );
        require(hasJoined[raffleId][msg.sender], "Did not participate");
        require(!hasClaimedRefund[raffleId][msg.sender], "Already claimed");
        require(block.timestamp <= raffle.claimDeadline, "Claim window expired");

        hasClaimedRefund[raffleId][msg.sender] = true;
        raffle.refundsClaimedCount++;

        if (raffle.refundsClaimedCount == raffle.participantCount) {
            raffle.state = RaffleState.Completed;
            _removeFromActiveRaffles(raffleId);
            emit RaffleCompleted(raffleId);
        }

        (bool success, ) = payable(msg.sender).call{value: ENTRY_FEE}("");
        require(success, "Transfer failed");

        emit RefundClaimed(raffleId, msg.sender);
    }

    // ═══════════════════════════════════════════════════════════
    //                  INTERNAL FUNCTIONS
    // ═══════════════════════════════════════════════════════════

    function _requestRandomness(uint256 raffleId) internal {
        Raffle storage raffle = raffles[raffleId];

        address provider = PYTH_ENTROPY.getDefaultProvider();
        uint256 fee = PYTH_ENTROPY.getFeeV2(provider, 0);
        uint256 reserved = getReservedFunds();

        require(address(this).balance >= fee + reserved, "Insufficient balance for VRF fee");

        raffle.state = RaffleState.PendingVRF;
        raffle.vrfRequestTime = block.timestamp;

        uint64 sequenceNumber = PYTH_ENTROPY.requestV2{value: fee}(
            provider,
            keccak256(abi.encodePacked(raffleId, block.timestamp)),
            0
        );

        vrfRequestToRaffle[sequenceNumber] = raffleId;

        emit RandomnessRequested(raffleId, sequenceNumber);
    }

    function _selectWinner(uint256 raffleId, uint256 randomNumber) internal {
        Raffle storage raffle = raffles[raffleId];

        require(raffle.state == RaffleState.PendingVRF, "Invalid state");

        uint256 winnerIndex = randomNumber % raffle.participantCount;
        address winner = raffleParticipants[raffleId][winnerIndex];

        raffle.winner = winner;
        raffle.claimDeadline = block.timestamp + CLAIM_WINDOW;
        raffle.state = RaffleState.WinnerSelected;

        emit WinnerSelected(raffleId, winner, raffle.rewardAmount);
    }

    function _enableRefunds(uint256 raffleId) internal {
        Raffle storage raffle = raffles[raffleId];

        raffle.claimDeadline = block.timestamp + CLAIM_WINDOW;
        raffle.state = RaffleState.RefundsEnabled;

        emit RefundsEnabled(raffleId, raffle.claimDeadline);
    }

    function _removeFromActiveRaffles(uint256 raffleId) internal {
        uint256 index = raffleIdToActiveIndex[raffleId];
        uint256 lastIndex = activeRaffleIds.length - 1;

        if (index != lastIndex) {
            uint256 lastRaffleId = activeRaffleIds[lastIndex];
            activeRaffleIds[index] = lastRaffleId;
            raffleIdToActiveIndex[lastRaffleId] = index;
        }

        activeRaffleIds.pop();
        delete raffleIdToActiveIndex[raffleId];
    }

    // ═══════════════════════════════════════════════════════════
    //                  VRF CALLBACK
    // ═══════════════════════════════════════════════════════════

    function entropyCallback(
        uint64 sequenceNumber,
        address,
        bytes32 randomNumber
    ) internal override {
        require(msg.sender == address(PYTH_ENTROPY), "Unauthorized");

        uint256 raffleId = vrfRequestToRaffle[sequenceNumber];
        require(raffleId != 0, "Unknown request");

        _selectWinner(raffleId, uint256(randomNumber));
    }

    function getEntropy() internal view override returns (address) {
        return address(PYTH_ENTROPY);
    }

    // ═══════════════════════════════════════════════════════════
    //                  VIEW FUNCTIONS
    // ═══════════════════════════════════════════════════════════

    function getReservedFunds() public view returns (uint256 reserved) {
        for (uint256 i = 0; i < activeRaffleIds.length; i++) {
            uint256 raffleId = activeRaffleIds[i];
            Raffle storage raffle = raffles[raffleId];

            if (raffle.state == RaffleState.Created || raffle.state == RaffleState.Active) {
                reserved += raffle.rewardAmount;
            } else if (raffle.state == RaffleState.PendingVRF) {
                reserved += raffle.rewardAmount;
            } else if (raffle.state == RaffleState.WinnerSelected && !raffle.rewardClaimed) {
                if (block.timestamp <= raffle.claimDeadline) {
                    reserved += raffle.rewardAmount;
                }
            } else if (raffle.state == RaffleState.RefundsEnabled || raffle.state == RaffleState.Cancelled) {
                if (block.timestamp <= raffle.claimDeadline) {
                    uint256 unclaimedRefunds = raffle.participantCount - raffle.refundsClaimedCount;
                    reserved += unclaimedRefunds * ENTRY_FEE;
                }
            }
        }
    }

    function getRaffleInfo(uint256 raffleId) external view returns (
        uint256 startTime,
        uint256 endTime,
        uint256 threshold,
        uint256 rewardAmount,
        uint256 participantCount,
        address winner,
        bool rewardClaimed,
        uint256 claimDeadline,
        uint256 refundsClaimedCount,
        RaffleState state
    ) {
        Raffle storage raffle = raffles[raffleId];
        return (
            raffle.startTime,
            raffle.endTime,
            raffle.threshold,
            raffle.rewardAmount,
            raffle.participantCount,
            raffle.winner,
            raffle.rewardClaimed,
            raffle.claimDeadline,
            raffle.refundsClaimedCount,
            raffle.state
        );
    }

    function getParticipants(uint256 raffleId) external view returns (address[] memory) {
        return raffleParticipants[raffleId];
    }

    function isParticipant(uint256 raffleId, address user) external view returns (bool) {
        return hasJoined[raffleId][user];
    }

    function canClaimRefund(uint256 raffleId, address user) external view returns (bool) {
        Raffle storage raffle = raffles[raffleId];
        return (
            (raffle.state == RaffleState.RefundsEnabled || raffle.state == RaffleState.Cancelled) &&
            hasJoined[raffleId][user] &&
            !hasClaimedRefund[raffleId][user] &&
            block.timestamp <= raffle.claimDeadline
        );
    }

    function canClaimReward(uint256 raffleId, address user) external view returns (bool) {
        Raffle storage raffle = raffles[raffleId];
        return (
            raffle.state == RaffleState.WinnerSelected &&
            raffle.winner == user &&
            !raffle.rewardClaimed &&
            block.timestamp <= raffle.claimDeadline
        );
    }

    function getWithdrawableAmount() external view returns (uint256) {
        return address(this).balance - getReservedFunds();
    }

    function getRaffleStats(uint256 raffleId) external view returns (
        bool isSuccessful,
        uint256 thresholdPercentage,
        uint256 totalRefundOwed,
        uint256 totalRefundsClaimed,
        bool isCompleted
    ) {
        Raffle storage raffle = raffles[raffleId];

        isSuccessful = raffle.participantCount >= raffle.threshold;
        thresholdPercentage = raffle.threshold > 0 ? (raffle.participantCount * 100) / raffle.threshold : 0;
        totalRefundOwed = isSuccessful ? 0 : raffle.participantCount * ENTRY_FEE;
        totalRefundsClaimed = raffle.refundsClaimedCount;
        isCompleted = raffle.state == RaffleState.Completed;
    }

    function getUserClaimStatus(uint256 raffleId, address user) external view returns (
        bool isWinner,
        bool canClaimRewardNow,
        bool canClaimRefundNow,
        uint256 claimableAmount
    ) {
        Raffle storage raffle = raffles[raffleId];

        isWinner = raffle.winner == user;

        canClaimRewardNow = (
            raffle.state == RaffleState.WinnerSelected &&
            isWinner &&
            !raffle.rewardClaimed &&
            block.timestamp <= raffle.claimDeadline
        );

        canClaimRefundNow = (
            (raffle.state == RaffleState.RefundsEnabled || raffle.state == RaffleState.Cancelled) &&
            hasJoined[raffleId][user] &&
            !hasClaimedRefund[raffleId][user] &&
            block.timestamp <= raffle.claimDeadline
        );

        if (canClaimRewardNow) {
            claimableAmount = raffle.rewardAmount;
        } else if (canClaimRefundNow) {
            claimableAmount = ENTRY_FEE;
        } else {
            claimableAmount = 0;
        }
    }

    function getActiveRaffleIds() external view returns (uint256[] memory) {
        return activeRaffleIds;
    }

    function getActiveRaffleCount() external view returns (uint256) {
        return activeRaffleIds.length;
    }

    receive() external payable {
        emit GasInjected(msg.sender, msg.value);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)

pragma solidity ^0.8.20;

/**
 * @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 EIP-1153 (transient storage) is available on the chain you're deploying at,
 * consider using {ReentrancyGuardTransient} instead.
 *
 * 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;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    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
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

        // 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;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}

File 3 of 9 : EntropyEvents.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

import "./EntropyStructs.sol";

// Deprecated -- these events are still emitted, but the lack of indexing
// makes them hard to use.
interface EntropyEvents {
    event Registered(EntropyStructs.ProviderInfo provider);

    event Requested(EntropyStructs.Request request);
    event RequestedWithCallback(
        address indexed provider,
        address indexed requestor,
        uint64 indexed sequenceNumber,
        bytes32 userRandomNumber,
        EntropyStructs.Request request
    );

    event Revealed(
        EntropyStructs.Request request,
        bytes32 userRevelation,
        bytes32 providerRevelation,
        bytes32 blockHash,
        bytes32 randomNumber
    );
    event RevealedWithCallback(
        EntropyStructs.Request request,
        bytes32 userRandomNumber,
        bytes32 providerRevelation,
        bytes32 randomNumber
    );

    event CallbackFailed(
        address indexed provider,
        address indexed requestor,
        uint64 indexed sequenceNumber,
        bytes32 userRandomNumber,
        bytes32 providerRevelation,
        bytes32 randomNumber,
        bytes errorCode
    );

    event ProviderFeeUpdated(address provider, uint128 oldFee, uint128 newFee);

    event ProviderDefaultGasLimitUpdated(
        address indexed provider,
        uint32 oldDefaultGasLimit,
        uint32 newDefaultGasLimit
    );

    event ProviderUriUpdated(address provider, bytes oldUri, bytes newUri);

    event ProviderFeeManagerUpdated(
        address provider,
        address oldFeeManager,
        address newFeeManager
    );
    event ProviderMaxNumHashesAdvanced(
        address provider,
        uint32 oldMaxNumHashes,
        uint32 newMaxNumHashes
    );

    event Withdrawal(
        address provider,
        address recipient,
        uint128 withdrawnAmount
    );
}

File 4 of 9 : EntropyEventsV2.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

import "./EntropyStructs.sol";

/**
 * @title EntropyEventsV2
 * @notice Interface defining events for the Entropy V2 system, which handles random number generation
 * and provider management on Ethereum.
 * @dev This interface is used to emit events that track the lifecycle of random number requests,
 * provider registrations, and system configurations.
 */
interface EntropyEventsV2 {
    /**
     * @notice Emitted when a new provider registers with the Entropy system
     * @param provider The address of the registered provider
     * @param extraArgs A field for extra data for forward compatibility.
     */
    event Registered(address indexed provider, bytes extraArgs);

    /**
     * @notice Emitted when a user requests a random number from a provider
     * @param provider The address of the provider handling the request
     * @param caller The address of the user requesting the random number
     * @param sequenceNumber A unique identifier for this request
     * @param userContribution The user's contribution to the random number
     * @param gasLimit The gas limit for the callback.
     * @param extraArgs A field for extra data for forward compatibility.
     */
    event Requested(
        address indexed provider,
        address indexed caller,
        uint64 indexed sequenceNumber,
        bytes32 userContribution,
        uint32 gasLimit,
        bytes extraArgs
    );

    /**
     * @notice Emitted when a provider reveals the generated random number
     * @param provider The address of the provider that generated the random number
     * @param caller The address of the user who requested the random number (and who receives a callback)
     * @param sequenceNumber The unique identifier of the request
     * @param randomNumber The generated random number
     * @param userContribution The user's contribution to the random number
     * @param providerContribution The provider's contribution to the random number
     * @param callbackFailed Whether the callback to the caller failed
     * @param callbackReturnValue Return value from the callback. If the callback failed, this field contains
     * the error code and any additional returned data. Note that "" often indicates an out-of-gas error.
     * If the callback returns more than 256 bytes, only the first 256 bytes of the callback return value are included.
     * @param callbackGasUsed How much gas the callback used.
     * @param extraArgs A field for extra data for forward compatibility.
     */
    event Revealed(
        address indexed provider,
        address indexed caller,
        uint64 indexed sequenceNumber,
        bytes32 randomNumber,
        bytes32 userContribution,
        bytes32 providerContribution,
        bool callbackFailed,
        bytes callbackReturnValue,
        uint32 callbackGasUsed,
        bytes extraArgs
    );

    /**
     * @notice Emitted when a provider updates their fee
     * @param provider The address of the provider updating their fee
     * @param oldFee The previous fee amount
     * @param newFee The new fee amount
     * @param extraArgs A field for extra data for forward compatibility.
     */
    event ProviderFeeUpdated(
        address indexed provider,
        uint128 oldFee,
        uint128 newFee,
        bytes extraArgs
    );

    /**
     * @notice Emitted when a provider updates their default gas limit
     * @param provider The address of the provider updating their gas limit
     * @param oldDefaultGasLimit The previous default gas limit
     * @param newDefaultGasLimit The new default gas limit
     * @param extraArgs A field for extra data for forward compatibility.
     */
    event ProviderDefaultGasLimitUpdated(
        address indexed provider,
        uint32 oldDefaultGasLimit,
        uint32 newDefaultGasLimit,
        bytes extraArgs
    );

    /**
     * @notice Emitted when a provider updates their URI
     * @param provider The address of the provider updating their URI
     * @param oldUri The previous URI
     * @param newUri The new URI
     * @param extraArgs A field for extra data for forward compatibility.
     */
    event ProviderUriUpdated(
        address indexed provider,
        bytes oldUri,
        bytes newUri,
        bytes extraArgs
    );

    /**
     * @notice Emitted when a provider updates their fee manager address
     * @param provider The address of the provider updating their fee manager
     * @param oldFeeManager The previous fee manager address
     * @param newFeeManager The new fee manager address
     * @param extraArgs A field for extra data for forward compatibility.
     */
    event ProviderFeeManagerUpdated(
        address indexed provider,
        address oldFeeManager,
        address newFeeManager,
        bytes extraArgs
    );

    /**
     * @notice Emitted when a provider updates their maximum number of hashes that can be advanced
     * @param provider The address of the provider updating their max hashes
     * @param oldMaxNumHashes The previous maximum number of hashes
     * @param newMaxNumHashes The new maximum number of hashes
     * @param extraArgs A field for extra data for forward compatibility.
     */
    event ProviderMaxNumHashesAdvanced(
        address indexed provider,
        uint32 oldMaxNumHashes,
        uint32 newMaxNumHashes,
        bytes extraArgs
    );

    /**
     * @notice Emitted when a provider withdraws their accumulated fees
     * @param provider The address of the provider withdrawing fees
     * @param recipient The address receiving the withdrawn fees
     * @param withdrawnAmount The amount of fees withdrawn
     * @param extraArgs A field for extra data for forward compatibility.
     */
    event Withdrawal(
        address indexed provider,
        address indexed recipient,
        uint128 withdrawnAmount,
        bytes extraArgs
    );
}

File 5 of 9 : EntropyStructs.sol
// SPDX-License-Identifier: Apache 2

pragma solidity ^0.8.0;

// This contract holds old versions of the Entropy structs that are no longer used for contract storage.
// However, they are still used in EntropyEvents to maintain the public interface of prior versions of
// the Entropy contract.
//
// See EntropyStructsV2 for the struct definitions currently in use.
contract EntropyStructs {
    struct ProviderInfo {
        uint128 feeInWei;
        uint128 accruedFeesInWei;
        // The commitment that the provider posted to the blockchain, and the sequence number
        // where they committed to this. This value is not advanced after the provider commits,
        // and instead is stored to help providers track where they are in the hash chain.
        bytes32 originalCommitment;
        uint64 originalCommitmentSequenceNumber;
        // Metadata for the current commitment. Providers may optionally use this field to help
        // manage rotations (i.e., to pick the sequence number from the correct hash chain).
        bytes commitmentMetadata;
        // Optional URI where clients can retrieve revelations for the provider.
        // Client SDKs can use this field to automatically determine how to retrieve random values for each provider.
        // TODO: specify the API that must be implemented at this URI
        bytes uri;
        // The first sequence number that is *not* included in the current commitment (i.e., an exclusive end index).
        // The contract maintains the invariant that sequenceNumber <= endSequenceNumber.
        // If sequenceNumber == endSequenceNumber, the provider must rotate their commitment to add additional random values.
        uint64 endSequenceNumber;
        // The sequence number that will be assigned to the next inbound user request.
        uint64 sequenceNumber;
        // The current commitment represents an index/value in the provider's hash chain.
        // These values are used to verify requests for future sequence numbers. Note that
        // currentCommitmentSequenceNumber < sequenceNumber.
        //
        // The currentCommitment advances forward through the provider's hash chain as values
        // are revealed on-chain.
        bytes32 currentCommitment;
        uint64 currentCommitmentSequenceNumber;
        // An address that is authorized to set / withdraw fees on behalf of this provider.
        address feeManager;
        // Maximum number of hashes to record in a request. This should be set according to the maximum gas limit
        // the provider supports for callbacks.
        uint32 maxNumHashes;
    }

    struct Request {
        // Storage slot 1 //
        address provider;
        uint64 sequenceNumber;
        // The number of hashes required to verify the provider revelation.
        uint32 numHashes;
        // Storage slot 2 //
        // The commitment is keccak256(userCommitment, providerCommitment). Storing the hash instead of both saves 20k gas by
        // eliminating 1 store.
        bytes32 commitment;
        // Storage slot 3 //
        // The number of the block where this request was created.
        // Note that we're using a uint64 such that we have an additional space for an address and other fields in
        // this storage slot. Although block.number returns a uint256, 64 bits should be plenty to index all of the
        // blocks ever generated.
        uint64 blockNumber;
        // The address that requested this random number.
        address requester;
        // If true, incorporate the blockhash of blockNumber into the generated random value.
        bool useBlockhash;
        // True if this is a request that expects a callback.
        bool isRequestWithCallback;
    }
}

File 6 of 9 : EntropyStructsV2.sol
// SPDX-License-Identifier: Apache 2

pragma solidity ^0.8.0;

contract EntropyStructsV2 {
    struct ProviderInfo {
        uint128 feeInWei;
        uint128 accruedFeesInWei;
        // The commitment that the provider posted to the blockchain, and the sequence number
        // where they committed to this. This value is not advanced after the provider commits,
        // and instead is stored to help providers track where they are in the hash chain.
        bytes32 originalCommitment;
        uint64 originalCommitmentSequenceNumber;
        // Metadata for the current commitment. Providers may optionally use this field to help
        // manage rotations (i.e., to pick the sequence number from the correct hash chain).
        bytes commitmentMetadata;
        // Optional URI where clients can retrieve revelations for the provider.
        // Client SDKs can use this field to automatically determine how to retrieve random values for each provider.
        // TODO: specify the API that must be implemented at this URI
        bytes uri;
        // The first sequence number that is *not* included in the current commitment (i.e., an exclusive end index).
        // The contract maintains the invariant that sequenceNumber <= endSequenceNumber.
        // If sequenceNumber == endSequenceNumber, the provider must rotate their commitment to add additional random values.
        uint64 endSequenceNumber;
        // The sequence number that will be assigned to the next inbound user request.
        uint64 sequenceNumber;
        // The current commitment represents an index/value in the provider's hash chain.
        // These values are used to verify requests for future sequence numbers. Note that
        // currentCommitmentSequenceNumber < sequenceNumber.
        //
        // The currentCommitment advances forward through the provider's hash chain as values
        // are revealed on-chain.
        bytes32 currentCommitment;
        uint64 currentCommitmentSequenceNumber;
        // An address that is authorized to set / withdraw fees on behalf of this provider.
        address feeManager;
        // Maximum number of hashes to record in a request. This should be set according to the maximum gas limit
        // the provider supports for callbacks.
        uint32 maxNumHashes;
        // Default gas limit to use for callbacks.
        uint32 defaultGasLimit;
    }

    struct Request {
        // Storage slot 1 //
        address provider;
        uint64 sequenceNumber;
        // The number of hashes required to verify the provider revelation.
        uint32 numHashes;
        // Storage slot 2 //
        // The commitment is keccak256(userCommitment, providerCommitment). Storing the hash instead of both saves 20k gas by
        // eliminating 1 store.
        bytes32 commitment;
        // Storage slot 3 //
        // The number of the block where this request was created.
        // Note that we're using a uint64 such that we have an additional space for an address and other fields in
        // this storage slot. Although block.number returns a uint256, 64 bits should be plenty to index all of the
        // blocks ever generated.
        uint64 blockNumber;
        // The address that requested this random number.
        address requester;
        // If true, incorporate the blockhash of blockNumber into the generated random value.
        bool useBlockhash;
        // Status flag for requests with callbacks. See EntropyConstants for the possible values of this flag.
        uint8 callbackStatus;
        // The gasLimit in units of 10k gas. (i.e., 2 = 20k gas). We're using units of 10k in order to fit this
        // field into the remaining 2 bytes of this storage slot. The dynamic range here is 10k - 655M, which should
        // cover all real-world use cases.
        uint16 gasLimit10k;
    }
}

// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.0;

import "./EntropyEvents.sol";
import "./EntropyEventsV2.sol";
import "./EntropyStructsV2.sol";
import "./IEntropyV2.sol";

/// @notice DEPRECATED: This interface is deprecated. Please use IEntropyV2 instead for new implementations.
/// IEntropyV2 provides better callback handling and improved functionality.
interface IEntropy is EntropyEvents, EntropyEventsV2, IEntropyV2 {
    // Register msg.sender as a randomness provider. The arguments are the provider's configuration parameters
    // and initial commitment. Re-registering the same provider rotates the provider's commitment (and updates
    // the feeInWei).
    //
    // chainLength is the number of values in the hash chain *including* the commitment, that is, chainLength >= 1.
    function register(
        uint128 feeInWei,
        bytes32 commitment,
        bytes calldata commitmentMetadata,
        uint64 chainLength,
        bytes calldata uri
    ) external;

    // Withdraw a portion of the accumulated fees for the provider msg.sender.
    // Calling this function will transfer `amount` wei to the caller (provided that they have accrued a sufficient
    // balance of fees in the contract).
    function withdraw(uint128 amount) external;

    // Withdraw a portion of the accumulated fees for provider. The msg.sender must be the fee manager for this provider.
    // Calling this function will transfer `amount` wei to the caller (provided that they have accrued a sufficient
    // balance of fees in the contract).
    function withdrawAsFeeManager(address provider, uint128 amount) external;

    // As a user, request a random number from `provider`. Prior to calling this method, the user should
    // generate a random number x and keep it secret. The user should then compute hash(x) and pass that
    // as the userCommitment argument. (You may call the constructUserCommitment method to compute the hash.)
    //
    // This method returns a sequence number. The user should pass this sequence number to
    // their chosen provider (the exact method for doing so will depend on the provider) to retrieve the provider's
    // number. The user should then call fulfillRequest to construct the final random number.
    //
    // WARNING: This method does NOT invoke a user callback. If you need callback functionality,
    // use requestV2 from the IEntropyV2 interface instead.
    //
    // This method will revert unless the caller provides a sufficient fee (at least getFee(provider)) as msg.value.
    // Note that excess value is *not* refunded to the caller.
    function request(
        address provider,
        bytes32 userCommitment,
        bool useBlockHash
    ) external payable returns (uint64 assignedSequenceNumber);

    // Request a random number. The method expects the provider address and a secret random number
    // in the arguments. It returns a sequence number.
    //
    // DEPRECATED: This method is deprecated. Please use requestV2 from the IEntropyV2 interface instead,
    // which provides better callback handling and gas limit control.
    //
    // The address calling this function should be a contract that inherits from the IEntropyConsumer interface.
    // The `entropyCallback` method on that interface will receive a callback with the generated random number.
    // `entropyCallback` will be run with the provider's default gas limit (see `getProviderInfo(provider).defaultGasLimit`).
    // If your callback needs additional gas, please use the function `requestv2` from `IEntropyV2` interface
    // with gasLimit as the input parameter.
    //
    // This method will revert unless the caller provides a sufficient fee (at least `getFee(provider)`) as msg.value.
    // Note that excess value is *not* refunded to the caller.
    function requestWithCallback(
        address provider,
        bytes32 userRandomNumber
    ) external payable returns (uint64 assignedSequenceNumber);

    // Fulfill a request for a random number. This method validates the provided userRandomness and provider's proof
    // against the corresponding commitments in the in-flight request. If both values are validated, this function returns
    // the corresponding random number.
    //
    // Note that this function can only be called once per in-flight request. Calling this function deletes the stored
    // request information (so that the contract doesn't use a linear amount of storage in the number of requests).
    // If you need to use the returned random number more than once, you are responsible for storing it.
    function reveal(
        address provider,
        uint64 sequenceNumber,
        bytes32 userRevelation,
        bytes32 providerRevelation
    ) external returns (bytes32 randomNumber);

    // Fulfill a request for a random number. This method validates the provided userRandomness
    // and provider's revelation against the corresponding commitment in the in-flight request. If both values are validated
    // and the requestor address is a contract address, this function calls the requester's entropyCallback method with the
    // sequence number, provider address and the random number as arguments. Else if the requestor is an EOA, it won't call it.
    //
    // Note that this function can only be called once per in-flight request. Calling this function deletes the stored
    // request information (so that the contract doesn't use a linear amount of storage in the number of requests).
    // If you need to use the returned random number more than once, you are responsible for storing it.
    //
    // Anyone can call this method to fulfill a request, but the callback will only be made to the original requester.
    function revealWithCallback(
        address provider,
        uint64 sequenceNumber,
        bytes32 userRandomNumber,
        bytes32 providerRevelation
    ) external;

    function getProviderInfo(
        address provider
    ) external view returns (EntropyStructs.ProviderInfo memory info);

    function getRequest(
        address provider,
        uint64 sequenceNumber
    ) external view returns (EntropyStructs.Request memory req);

    // Get the fee charged by provider for a request with the default gasLimit (`request` or `requestWithCallback`).
    // If you are calling any of the `requestV2` methods, please use `getFeeV2`.
    function getFee(address provider) external view returns (uint128 feeAmount);

    function getAccruedPythFees()
        external
        view
        returns (uint128 accruedPythFeesInWei);

    function setProviderFee(uint128 newFeeInWei) external;

    function setProviderFeeAsFeeManager(
        address provider,
        uint128 newFeeInWei
    ) external;

    function setProviderUri(bytes calldata newUri) external;

    // Set manager as the fee manager for the provider msg.sender.
    // After calling this function, manager will be able to set the provider's fees and withdraw them.
    // Only one address can be the fee manager for a provider at a time -- calling this function again with a new value
    // will override the previous value. Call this function with the all-zero address to disable the fee manager role.
    function setFeeManager(address manager) external;

    // Set the maximum number of hashes to record in a request. This should be set according to the maximum gas limit
    // the provider supports for callbacks.
    function setMaxNumHashes(uint32 maxNumHashes) external;

    // Set the default gas limit for a request. If 0, no
    function setDefaultGasLimit(uint32 gasLimit) external;

    // Advance the provider commitment and increase the sequence number.
    // This is used to reduce the `numHashes` required for future requests which leads to reduced gas usage.
    function advanceProviderCommitment(
        address provider,
        uint64 advancedSequenceNumber,
        bytes32 providerRevelation
    ) external;

    function constructUserCommitment(
        bytes32 userRandomness
    ) external pure returns (bytes32 userCommitment);

    function combineRandomValues(
        bytes32 userRandomness,
        bytes32 providerRandomness,
        bytes32 blockHash
    ) external pure returns (bytes32 combinedRandomness);
}

// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.0;

abstract contract IEntropyConsumer {
    // This method is called by Entropy to provide the random number to the consumer.
    // It asserts that the msg.sender is the Entropy contract. It is not meant to be
    // override by the consumer.
    function _entropyCallback(
        uint64 sequence,
        address provider,
        bytes32 randomNumber
    ) external {
        address entropy = getEntropy();
        require(entropy != address(0), "Entropy address not set");
        require(msg.sender == entropy, "Only Entropy can call this function");

        entropyCallback(sequence, provider, randomNumber);
    }

    // getEntropy returns Entropy contract address. The method is being used to check that the
    // callback is indeed from Entropy contract. The consumer is expected to implement this method.
    // Entropy address can be found here - https://docs.pyth.network/entropy/contract-addresses
    function getEntropy() internal view virtual returns (address);

    // This method is expected to be implemented by the consumer to handle the random number.
    // It will be called by _entropyCallback after _entropyCallback ensures that the call is
    // indeed from Entropy contract.
    function entropyCallback(
        uint64 sequence,
        address provider,
        bytes32 randomNumber
    ) internal virtual;
}

// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.0;

import "./EntropyEvents.sol";
import "./EntropyEventsV2.sol";
import "./EntropyStructsV2.sol";

interface IEntropyV2 is EntropyEventsV2 {
    /// @notice Request a random number using the default provider with default gas limit
    /// @return assignedSequenceNumber A unique identifier for this request
    /// @dev The address calling this function should be a contract that inherits from the IEntropyConsumer interface.
    /// The `entropyCallback` method on that interface will receive a callback with the returned sequence number and
    /// the generated random number.
    ///
    /// `entropyCallback` will be run with the provider's configured default gas limit.
    ///
    /// This method will revert unless the caller provides a sufficient fee (at least `getFeeV2()`) as msg.value.
    /// Note that the fee can change over time. Callers of this method should explicitly compute `getFeeV2()`
    /// prior to each invocation (as opposed to hardcoding a value). Further note that excess value is *not* refunded to the caller.
    ///
    /// Note that this method uses an in-contract PRNG to generate the user's contribution to the random number.
    /// This approach modifies the security guarantees such that a dishonest validator and provider can
    /// collude to manipulate the result (as opposed to a malicious user and provider). That is, the user
    /// now trusts the validator honestly draw a random number. If you wish to avoid this trust assumption,
    /// call a variant of `requestV2` that accepts a `userRandomNumber` parameter.
    function requestV2()
        external
        payable
        returns (uint64 assignedSequenceNumber);

    /// @notice Request a random number using the default provider with specified gas limit
    /// @param gasLimit The gas limit for the callback function.
    /// @return assignedSequenceNumber A unique identifier for this request
    /// @dev The address calling this function should be a contract that inherits from the IEntropyConsumer interface.
    /// The `entropyCallback` method on that interface will receive a callback with the returned sequence number and
    /// the generated random number.
    ///
    /// `entropyCallback` will be run with the `gasLimit` provided to this function.
    /// The `gasLimit` will be rounded up to a multiple of 10k (e.g., 19000 -> 20000), and furthermore is lower bounded
    /// by the provider's configured default limit.
    ///
    /// This method will revert unless the caller provides a sufficient fee (at least `getFeeV2(gasLimit)`) as msg.value.
    /// Note that the fee can change over time. Callers of this method should explicitly compute `getFeeV2(gasLimit)`
    /// prior to each invocation (as opposed to hardcoding a value). Further note that excess value is *not* refunded to the caller.
    ///
    /// Note that this method uses an in-contract PRNG to generate the user's contribution to the random number.
    /// This approach modifies the security guarantees such that a dishonest validator and provider can
    /// collude to manipulate the result (as opposed to a malicious user and provider). That is, the user
    /// now trusts the validator honestly draw a random number. If you wish to avoid this trust assumption,
    /// call a variant of `requestV2` that accepts a `userRandomNumber` parameter.
    function requestV2(
        uint32 gasLimit
    ) external payable returns (uint64 assignedSequenceNumber);

    /// @notice Request a random number from a specific provider with specified gas limit
    /// @param provider The address of the provider to request from
    /// @param gasLimit The gas limit for the callback function
    /// @return assignedSequenceNumber A unique identifier for this request
    /// @dev The address calling this function should be a contract that inherits from the IEntropyConsumer interface.
    /// The `entropyCallback` method on that interface will receive a callback with the returned sequence number and
    /// the generated random number.
    ///
    /// `entropyCallback` will be run with the `gasLimit` provided to this function.
    /// The `gasLimit` will be rounded up to a multiple of 10k (e.g., 19000 -> 20000), and furthermore is lower bounded
    /// by the provider's configured default limit.
    ///
    /// This method will revert unless the caller provides a sufficient fee (at least `getFeeV2(provider, gasLimit)`) as msg.value.
    /// Note that provider fees can change over time. Callers of this method should explicitly compute `getFeeV2(provider, gasLimit)`
    /// prior to each invocation (as opposed to hardcoding a value). Further note that excess value is *not* refunded to the caller.
    ///
    /// Note that this method uses an in-contract PRNG to generate the user's contribution to the random number.
    /// This approach modifies the security guarantees such that a dishonest validator and provider can
    /// collude to manipulate the result (as opposed to a malicious user and provider). That is, the user
    /// now trusts the validator honestly draw a random number. If you wish to avoid this trust assumption,
    /// call a variant of `requestV2` that accepts a `userRandomNumber` parameter.
    function requestV2(
        address provider,
        uint32 gasLimit
    ) external payable returns (uint64 assignedSequenceNumber);

    /// @notice Request a random number from a specific provider with a user-provided random number and gas limit
    /// @param provider The address of the provider to request from
    /// @param userRandomNumber A random number provided by the user for additional entropy
    /// @param gasLimit The gas limit for the callback function. Pass 0 to get a sane default value -- see note below.
    /// @return assignedSequenceNumber A unique identifier for this request
    /// @dev The address calling this function should be a contract that inherits from the IEntropyConsumer interface.
    /// The `entropyCallback` method on that interface will receive a callback with the returned sequence number and
    /// the generated random number.
    ///
    /// `entropyCallback` will be run with the `gasLimit` provided to this function.
    /// The `gasLimit` will be rounded up to a multiple of 10k (e.g., 19000 -> 20000), and furthermore is lower bounded
    /// by the provider's configured default limit.
    ///
    /// This method will revert unless the caller provides a sufficient fee (at least `getFeeV2(provider, gasLimit)`) as msg.value.
    /// Note that provider fees can change over time. Callers of this method should explicitly compute `getFeeV2(provider, gasLimit)`
    /// prior to each invocation (as opposed to hardcoding a value). Further note that excess value is *not* refunded to the caller.
    function requestV2(
        address provider,
        bytes32 userRandomNumber,
        uint32 gasLimit
    ) external payable returns (uint64 assignedSequenceNumber);

    /// @notice Get information about a specific entropy provider
    /// @param provider The address of the provider to query
    /// @return info The provider information including configuration, fees, and operational status
    /// @dev This method returns detailed information about a provider's configuration and capabilities.
    /// The returned ProviderInfo struct contains information such as the provider's fee structure and gas limits.
    function getProviderInfoV2(
        address provider
    ) external view returns (EntropyStructsV2.ProviderInfo memory info);

    /// @notice Get the address of the default entropy provider
    /// @return provider The address of the default provider
    /// @dev This method returns the address of the provider that will be used when no specific provider is specified
    /// in the requestV2 calls. The default provider can be used to get the base fee and gas limit information.
    function getDefaultProvider() external view returns (address provider);

    /// @notice Get information about a specific request
    /// @param provider The address of the provider that handled the request
    /// @param sequenceNumber The unique identifier of the request
    /// @return req The request information including status, random number, and other metadata
    /// @dev This method allows querying the state of a previously made request. The returned Request struct
    /// contains information about whether the request was fulfilled, the generated random number (if available),
    /// and other metadata about the request.
    function getRequestV2(
        address provider,
        uint64 sequenceNumber
    ) external view returns (EntropyStructsV2.Request memory req);

    /// @notice Get the fee charged by the default provider for the default gas limit
    /// @return feeAmount The fee amount in wei
    /// @dev This method returns the base fee required to make a request using the default provider with
    /// the default gas limit. This fee should be passed as msg.value when calling requestV2().
    /// The fee can change over time, so this method should be called before each request.
    function getFeeV2() external view returns (uint128 feeAmount);

    /// @notice Get the fee charged by the default provider for a specific gas limit
    /// @param gasLimit The gas limit for the callback function
    /// @return feeAmount The fee amount in wei
    /// @dev This method returns the fee required to make a request using the default provider with
    /// the specified gas limit. This fee should be passed as msg.value when calling requestV2(gasLimit).
    /// The fee can change over time, so this method should be called before each request.
    function getFeeV2(
        uint32 gasLimit
    ) external view returns (uint128 feeAmount);

    /// @notice Get the fee charged by a specific provider for a request with a given gas limit
    /// @param provider The address of the provider to query
    /// @param gasLimit The gas limit for the callback function
    /// @return feeAmount The fee amount in wei
    /// @dev This method returns the fee required to make a request using the specified provider with
    /// the given gas limit. This fee should be passed as msg.value when calling requestV2(provider, gasLimit)
    /// or requestV2(provider, userRandomNumber, gasLimit). The fee can change over time, so this method
    /// should be called before each request.
    function getFeeV2(
        address provider,
        uint32 gasLimit
    ) external view returns (uint128 feeAmount);
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"GasInjected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":true,"internalType":"address","name":"participant","type":"address"},{"indexed":false,"internalType":"uint256","name":"participantCount","type":"uint256"}],"name":"ParticipantJoined","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"RaffleCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"RaffleCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"threshold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardAmount","type":"uint256"}],"name":"RaffleCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"sequenceNumber","type":"uint64"}],"name":"RandomnessRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":true,"internalType":"address","name":"participant","type":"address"}],"name":"RefundClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"claimDeadline","type":"uint256"}],"name":"RefundsEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":true,"internalType":"address","name":"winner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TreasuryTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":true,"internalType":"address","name":"winner","type":"address"},{"indexed":false,"internalType":"uint256","name":"rewardAmount","type":"uint256"}],"name":"WinnerSelected","type":"event"},{"inputs":[],"name":"ADMIN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CLAIM_WINDOW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ENTRY_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PYTH_ENTROPY","outputs":[{"internalType":"contract IEntropy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VRF_TIMEOUT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"internalType":"address","name":"provider","type":"address"},{"internalType":"bytes32","name":"randomNumber","type":"bytes32"}],"name":"_entropyCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"activeRaffleIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"canClaimRefund","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"canClaimReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"cancelStuckRaffle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"claimRefund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"claimReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"}],"name":"createRaffle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"finalizeRaffle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getActiveRaffleCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getActiveRaffleIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"getParticipants","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"getRaffleInfo","outputs":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"internalType":"uint256","name":"participantCount","type":"uint256"},{"internalType":"address","name":"winner","type":"address"},{"internalType":"bool","name":"rewardClaimed","type":"bool"},{"internalType":"uint256","name":"claimDeadline","type":"uint256"},{"internalType":"uint256","name":"refundsClaimedCount","type":"uint256"},{"internalType":"enum OneMON.RaffleState","name":"state","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"getRaffleStats","outputs":[{"internalType":"bool","name":"isSuccessful","type":"bool"},{"internalType":"uint256","name":"thresholdPercentage","type":"uint256"},{"internalType":"uint256","name":"totalRefundOwed","type":"uint256"},{"internalType":"uint256","name":"totalRefundsClaimed","type":"uint256"},{"internalType":"bool","name":"isCompleted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReservedFunds","outputs":[{"internalType":"uint256","name":"reserved","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"getUserClaimStatus","outputs":[{"internalType":"bool","name":"isWinner","type":"bool"},{"internalType":"bool","name":"canClaimRewardNow","type":"bool"},{"internalType":"bool","name":"canClaimRefundNow","type":"bool"},{"internalType":"uint256","name":"claimableAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawableAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"hasClaimedRefund","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"hasJoined","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"injectGas","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"isParticipant","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"joinRaffle","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"raffleId","type":"uint256"}],"name":"markRaffleCompleted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nextRaffleId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"raffleIdToActiveIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"raffleParticipants","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"raffles","outputs":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"internalType":"uint256","name":"participantCount","type":"uint256"},{"internalType":"address","name":"winner","type":"address"},{"internalType":"bool","name":"rewardClaimed","type":"bool"},{"internalType":"uint256","name":"claimDeadline","type":"uint256"},{"internalType":"uint256","name":"refundsClaimedCount","type":"uint256"},{"internalType":"uint256","name":"vrfRequestTime","type":"uint256"},{"internalType":"enum OneMON.RaffleState","name":"state","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"treasuryTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"vrfRequestToRaffle","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

608060405260018055348015601357600080fd5b5060016000819055506152bc8061002b6000396000f3fe6080604052600436106102085760003560e01c8063857f675d11610118578063b1ddd82a116100a0578063d1cfcd0d1161006f578063d1cfcd0d1461082e578063dad717741461086f578063effbe39a1461089a578063f4d1c5f6146108c3578063f6d361cc146108ee5761025d565b8063b1ddd82a1461074e578063c04b11f01461078b578063c1e3bd3e146107c8578063c7d91d27146108055761025d565b80639eb94824116100e75780639eb94824146106675780639f34fc8014610692578063ae169a50146106bd578063afb218f5146106e6578063b154afc3146107115761025d565b8063857f675d1461059757806390be10cc146105c25780639827ba57146105ed5780639c5b281d1461062a5761025d565b8063485de6ff1161019b578063681947191161016a57806368194719146104ab578063758d9b89146104e85780637befbefc146105255780637f200416146105625780638458e3e41461056c5761025d565b8063485de6ff146103d557806352a5f1f8146104125780635b7baf641461043b5780635d4bc0ce146104645761025d565b80632c2aa24e116101d75780632c2aa24e146103255780632d2c55651461036557806339510c85146103905780634758eca9146103b95761025d565b8063186a646a146102625780632192e4fa1461028b57806327d7e46d146102b45780632a0acc6a146102fa5761025d565b3661025d573373ffffffffffffffffffffffffffffffffffffffff167f0b65a8269cbde15c758c61aa6aca57ed9f9598dc5667cbd823244c449f5e572d3460405161025391906137fa565b60405180910390a2005b600080fd5b34801561026e57600080fd5b5061028960048036038101906102849190613846565b610919565b005b34801561029757600080fd5b506102b260048036038101906102ad9190613846565b610b96565b005b3480156102c057600080fd5b506102db60048036038101906102d69190613846565b610d89565b6040516102f19a99989796959493929190613946565b60405180910390f35b34801561030657600080fd5b5061030f610e3d565b60405161031c91906139e2565b60405180910390f35b34801561033157600080fd5b5061034c60048036038101906103479190613a29565b610e55565b60405161035c9493929190613a69565b60405180910390f35b34801561037157600080fd5b5061037a6110c5565b60405161038791906139e2565b60405180910390f35b34801561039c57600080fd5b506103b760048036038101906103b29190613aae565b6110dd565b005b6103d360048036038101906103ce9190613846565b6114ed565b005b3480156103e157600080fd5b506103fc60048036038101906103f79190613a29565b6118fa565b6040516104099190613b15565b60405180910390f35b34801561041e57600080fd5b5061043960048036038101906104349190613ba6565b6119da565b005b34801561044757600080fd5b50610462600480360381019061045d9190613846565b611ad4565b005b34801561047057600080fd5b5061048b60048036038101906104869190613846565b611f27565b6040516104a29b9a99989796959493929190613bf9565b60405180910390f35b3480156104b757600080fd5b506104d260048036038101906104cd9190613a29565b611fbb565b6040516104df9190613b15565b60405180910390f35b3480156104f457600080fd5b5061050f600480360381019061050a9190613a29565b611fea565b60405161051c9190613b15565b60405180910390f35b34801561053157600080fd5b5061054c60048036038101906105479190613a29565b612052565b6040516105599190613b15565b60405180910390f35b61056a6121c8565b005b34801561057857600080fd5b506105816122dd565b60405161058e91906137fa565b60405180910390f35b3480156105a357600080fd5b506105ac6122e3565b6040516105b991906137fa565b60405180910390f35b3480156105ce57600080fd5b506105d7612571565b6040516105e491906137fa565b60405180910390f35b3480156105f957600080fd5b50610614600480360381019061060f9190613846565b61258b565b60405161062191906137fa565b60405180910390f35b34801561063657600080fd5b50610651600480360381019061064c9190613ca4565b6125af565b60405161065e91906137fa565b60405180910390f35b34801561067357600080fd5b5061067c6125c7565b6040516106899190613d8f565b60405180910390f35b34801561069e57600080fd5b506106a761261f565b6040516106b491906137fa565b60405180910390f35b3480156106c957600080fd5b506106e460048036038101906106df9190613846565b612626565b005b3480156106f257600080fd5b506106fb612978565b6040516107089190613e10565b60405180910390f35b34801561071d57600080fd5b5061073860048036038101906107339190613a29565b612990565b6040516107459190613b15565b60405180910390f35b34801561075a57600080fd5b5061077560048036038101906107709190613e2b565b6129bf565b60405161078291906139e2565b60405180910390f35b34801561079757600080fd5b506107b260048036038101906107ad9190613846565b612a0d565b6040516107bf91906137fa565b60405180910390f35b3480156107d457600080fd5b506107ef60048036038101906107ea9190613846565b612a25565b6040516107fc9190613f29565b60405180910390f35b34801561081157600080fd5b5061082c60048036038101906108279190613846565b612ac6565b005b34801561083a57600080fd5b5061085560048036038101906108509190613846565b612cfc565b604051610866959493929190613f4b565b60405180910390f35b34801561087b57600080fd5b50610884612dd1565b60405161089191906137fa565b60405180910390f35b3480156108a657600080fd5b506108c160048036038101906108bc9190613846565b612dde565b005b3480156108cf57600080fd5b506108d861300f565b6040516108e591906137fa565b60405180910390f35b3480156108fa57600080fd5b50610903613016565b60405161091091906137fa565b60405180910390f35b7314d5aa304af9c1aeff1f37375f85ba0cbfb6c10473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461099b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099290613ffb565b60405180910390fd5b6109a3613022565b6000600260008381526020019081526020016000209050600160068111156109ce576109cd6138cf565b5b8160090160009054906101000a900460ff1660068111156109f2576109f16138cf565b5b1480610a33575060006006811115610a0d57610a0c6138cf565b5b8160090160009054906101000a900460ff166006811115610a3157610a306138cf565b5b145b610a72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6990614067565b60405180910390fd5b80600101544211610ab8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aaf906140d3565b60405180910390fd5b6000816004015403610b625760058160090160006101000a81548160ff02191690836006811115610aec57610aeb6138cf565b5b0217905550610afa82613068565b817f4b065d94bb5f805836b9aefd08a7b4388cfdd8d346a56ef0a4a547dbca8b8f1f604051610b289061413f565b60405180910390a2817f1e15dbf45ae533c182513b50c5b94530ab41942881a0bb1dc4206313d8b4115960405160405180910390a2610b8a565b8060020154816004015410610b7f57610b7a82613141565b610b89565b610b8882613444565b5b5b50610b936134df565b50565b7314d5aa304af9c1aeff1f37375f85ba0cbfb6c10473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0f90613ffb565b60405180910390fd5b610c20613022565b600060026000838152602001908152602001600020905060026006811115610c4b57610c4a6138cf565b5b8160090160009054906101000a900460ff166006811115610c6f57610c6e6138cf565b5b14610caf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca6906141ab565b60405180910390fd5b620151808160080154610cc291906141fa565b4211610d03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cfa9061427a565b60405180910390fd5b60068160090160006101000a81548160ff02191690836006811115610d2b57610d2a6138cf565b5b02179055506203f48042610d3f91906141fa565b8160060181905550817f4b065d94bb5f805836b9aefd08a7b4388cfdd8d346a56ef0a4a547dbca8b8f1f604051610d75906142e6565b60405180910390a250610d866134df565b50565b6000806000806000806000806000806000600260008d81526020019081526020016000209050806000015481600101548260020154836003015484600401548560050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660050160149054906101000a900460ff16876006015488600701548960090160009054906101000a900460ff169a509a509a509a509a509a509a509a509a509a50509193959799509193959799565b7314d5aa304af9c1aeff1f37375f85ba0cbfb6c10481565b60008060008060006002600088815260200190815260200160002090508573ffffffffffffffffffffffffffffffffffffffff168160050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614945060036006811115610edb57610eda6138cf565b5b8160090160009054906101000a900460ff166006811115610eff57610efe6138cf565b5b148015610f095750845b8015610f2457508060050160149054906101000a900460ff16155b8015610f34575080600601544211155b935060046006811115610f4a57610f496138cf565b5b8160090160009054906101000a900460ff166006811115610f6e57610f6d6138cf565b5b1480610fae5750600680811115610f8857610f876138cf565b5b8160090160009054906101000a900460ff166006811115610fac57610fab6138cf565b5b145b801561101457506004600088815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b801561107b57506005600088815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b801561108b575080600601544211155b9250831561109f57806003015491506110bb565b82156110b557670de0b6b3a764000091506110ba565b600091505b5b5092959194509250565b736779387e262e3ec8c81f62dcd3b2348931b5254d81565b7314d5aa304af9c1aeff1f37375f85ba0cbfb6c10473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461115f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161115690613ffb565b60405180910390fd5b8284106111a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119890614352565b60405180910390fd5b4284116111e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111da906143be565b60405180910390fd5b60008211611226576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121d9061442a565b60405180910390fd5b60008111611269576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126090614496565b60405180910390fd5b6112716122e3565b8161127c91906141fa565b4710156112be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b590614502565b60405180910390fd5b6000600160008154809291906112d390614522565b91905055905060405180610160016040528086815260200185815260200184815260200183815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160001515815260200160008152602001600081526020016000815260200160006006811115611353576113526138cf565b5b81525060026000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060c08201518160050160146101000a81548160ff02191690831515021790555060e08201518160060155610100820151816007015561012082015181600801556101408201518160090160006101000a81548160ff0219169083600681111561144e5761144d6138cf565b5b021790555090505060078190806001815401808255809150506001900390600052602060002001600090919091909150556001600780549050611491919061456a565b6008600083815260200190815260200160002081905550807ffcc13aaaf4660281e2662ae91069e5f95cc7863d25a6a68e620806a99354fa1a868686866040516114de949392919061459e565b60405180910390a25050505050565b6114f5613022565b6000600260008381526020019081526020016000209050600060068111156115205761151f6138cf565b5b8160090160009054906101000a900460ff166006811115611544576115436138cf565b5b148061158557506001600681111561155f5761155e6138cf565b5b8160090160009054906101000a900460ff166006811115611583576115826138cf565b5b145b6115c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bb9061462f565b60405180910390fd5b806000015442101561160b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116029061469b565b60405180910390fd5b80600101544210611651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164890614707565b60405180910390fd5b670de0b6b3a7640000341461169b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169290614773565b60405180910390fd5b6004600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611739576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611730906147df565b60405180910390fd5b6000600681111561174d5761174c6138cf565b5b8160090160009054906101000a900460ff166006811115611771576117706138cf565b5b036117a45760018160090160006101000a81548160ff0219169083600681111561179e5761179d6138cf565b5b02179055505b60016004600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060036000838152602001908152602001600020339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600401600081548092919061189690614522565b91905055503373ffffffffffffffffffffffffffffffffffffffff16827f338e0cd33c4e120afcd73f43f082fd8940ed67ac35180d278d2eb4f3ed51d92e83600401546040516118e691906137fa565b60405180910390a3506118f76134df565b50565b60008060026000858152602001908152602001600020905060036006811115611926576119256138cf565b5b8160090160009054906101000a900460ff16600681111561194a576119496138cf565b5b1480156119a657508273ffffffffffffffffffffffffffffffffffffffff168160050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b80156119c157508060050160149054906101000a900460ff16155b80156119d1575080600601544211155b91505092915050565b60006119e46134e9565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611a55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4c9061484b565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611ac3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aba906148dd565b60405180910390fd5b611ace848484613505565b50505050565b611adc613022565b600060026000838152602001908152602001600020905060046006811115611b0757611b066138cf565b5b8160090160009054906101000a900460ff166006811115611b2b57611b2a6138cf565b5b1480611b6b5750600680811115611b4557611b446138cf565b5b8160090160009054906101000a900460ff166006811115611b6957611b686138cf565b5b145b611baa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba190614949565b60405180910390fd5b6004600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611c47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3e906149b5565b60405180910390fd5b6005600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611ce5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cdc90614a21565b60405180910390fd5b8060060154421115611d2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d2390614a8d565b60405180910390fd5b60016005600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550806007016000815480929190611daa90614522565b91905055508060040154816007015403611e225760058160090160006101000a81548160ff02191690836006811115611de657611de56138cf565b5b0217905550611df482613068565b817f1e15dbf45ae533c182513b50c5b94530ab41942881a0bb1dc4206313d8b4115960405160405180910390a25b60003373ffffffffffffffffffffffffffffffffffffffff16670de0b6b3a7640000604051611e5090614ade565b60006040518083038185875af1925050503d8060008114611e8d576040519150601f19603f3d011682016040523d82523d6000602084013e611e92565b606091505b5050905080611ed6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ecd90614b3f565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16837fd86f3d2d747d5d831df461fda7bf64b7d9d57ff4b8b3fe58836776cf90a6bda560405160405180910390a35050611f246134df565b50565b60026020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060050160149054906101000a900460ff16908060060154908060070154908060080154908060090160009054906101000a900460ff1690508b565b60046020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b60006004600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000806002600085815260200190815260200160002090506004600681111561207e5761207d6138cf565b5b8160090160009054906101000a900460ff1660068111156120a2576120a16138cf565b5b14806120e257506006808111156120bc576120bb6138cf565b5b8160090160009054906101000a900460ff1660068111156120e0576120df6138cf565b5b145b801561214857506004600085815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b80156121af57506005600085815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b80156121bf575080600601544211155b91505092915050565b7314d5aa304af9c1aeff1f37375f85ba0cbfb6c10473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461224a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161224190613ffb565b60405180910390fd5b6000341161228d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228490614bab565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f0b65a8269cbde15c758c61aa6aca57ed9f9598dc5667cbd823244c449f5e572d346040516122d391906137fa565b60405180910390a2565b60015481565b600080600090505b60078054905081101561256d5760006007828154811061230e5761230d614bcb565b5b90600052602060002001549050600060026000838152602001908152602001600020905060006006811115612346576123456138cf565b5b8160090160009054906101000a900460ff16600681111561236a576123696138cf565b5b14806123ab575060016006811115612385576123846138cf565b5b8160090160009054906101000a900460ff1660068111156123a9576123a86138cf565b5b145b156123c7578060030154846123c091906141fa565b935061255e565b600260068111156123db576123da6138cf565b5b8160090160009054906101000a900460ff1660068111156123ff576123fe6138cf565b5b0361241b5780600301548461241491906141fa565b935061255d565b6003600681111561242f5761242e6138cf565b5b8160090160009054906101000a900460ff166006811115612453576124526138cf565b5b14801561246f57508060050160149054906101000a900460ff16155b1561249757806006015442116124925780600301548461248f91906141fa565b93505b61255c565b600460068111156124ab576124aa6138cf565b5b8160090160009054906101000a900460ff1660068111156124cf576124ce6138cf565b5b148061250f57506006808111156124e9576124e86138cf565b5b8160090160009054906101000a900460ff16600681111561250d5761250c6138cf565b5b145b1561255b578060060154421161255a57600081600701548260040154612535919061456a565b9050670de0b6b3a76400008161254b9190614bfa565b8561255691906141fa565b9450505b5b5b5b5b505080806001019150506122eb565b5090565b600061257b6122e3565b47612586919061456a565b905090565b6007818154811061259b57600080fd5b906000526020600020016000915090505481565b60066020528060005260406000206000915090505481565b6060600780548060200260200160405190810160405280929190818152602001828054801561261557602002820191906000526020600020905b815481526020019060010190808311612601575b5050505050905090565b6203f48081565b61262e613022565b600060026000838152602001908152602001600020905060036006811115612659576126586138cf565b5b8160090160009054906101000a900460ff16600681111561267d5761267c6138cf565b5b146126bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126b490614c88565b60405180910390fd5b8060050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461274f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161274690614cf4565b60405180910390fd5b8060050160149054906101000a900460ff16156127a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279890614a21565b60405180910390fd5b80600601544211156127e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127df90614a8d565b60405180910390fd5b60018160050160146101000a81548160ff02191690831515021790555060058160090160006101000a81548160ff0219169083600681111561282d5761282c6138cf565b5b021790555061283b82613068565b60003373ffffffffffffffffffffffffffffffffffffffff16826003015460405161286590614ade565b60006040518083038185875af1925050503d80600081146128a2576040519150601f19603f3d011682016040523d82523d6000602084013e6128a7565b606091505b50509050806128eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128e290614b3f565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16837f24b5efa61dd1cfc659205a97fb8ed868f3cb8c81922bab2b96423e5de1de2cb7846003015460405161293691906137fa565b60405180910390a3827f1e15dbf45ae533c182513b50c5b94530ab41942881a0bb1dc4206313d8b4115960405160405180910390a250506129756134df565b50565b73d458261e832415cfd3bae5e416fdf3230ce6f13481565b60056020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b600360205281600052604060002081815481106129db57600080fd5b906000526020600020016000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60086020528060005260406000206000915090505481565b606060036000838152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015612aba57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311612a70575b50505050509050919050565b7314d5aa304af9c1aeff1f37375f85ba0cbfb6c10473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612b48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b3f90613ffb565b60405180910390fd5b6000600260008381526020019081526020016000209050600060036006811115612b7557612b746138cf565b5b8260090160009054906101000a900460ff166006811115612b9957612b986138cf565b5b148015612ba95750816006015442115b9050600060046006811115612bc157612bc06138cf565b5b8360090160009054906101000a900460ff166006811115612be557612be46138cf565b5b148015612bf55750826006015442115b90506000600680811115612c0c57612c0b6138cf565b5b8460090160009054906101000a900460ff166006811115612c3057612c2f6138cf565b5b148015612c405750836006015442115b90508280612c4b5750815b80612c535750805b612c92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8990614d60565b60405180910390fd5b60058460090160006101000a81548160ff02191690836006811115612cba57612cb96138cf565b5b0217905550612cc885613068565b847f1e15dbf45ae533c182513b50c5b94530ab41942881a0bb1dc4206313d8b4115960405160405180910390a25050505050565b60008060008060008060026000888152602001908152602001600020905080600201548160040154101595506000816002015411612d3b576000612d5c565b806002015460648260040154612d519190614bfa565b612d5b9190614daf565b5b945085612d8057670de0b6b3a76400008160040154612d7b9190614bfa565b612d83565b60005b93508060070154925060056006811115612da057612d9f6138cf565b5b8160090160009054906101000a900460ff166006811115612dc457612dc36138cf565b5b1491505091939590929450565b6000600780549050905090565b7314d5aa304af9c1aeff1f37375f85ba0cbfb6c10473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612e60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e5790613ffb565b60405180910390fd5b612e68613022565b60008111612eab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ea290614e2c565b60405180910390fd5b6000612eb56122e3565b905060008147612ec5919061456a565b905080831115612f0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0190614e98565b60405180910390fd5b6000736779387e262e3ec8c81f62dcd3b2348931b5254d73ffffffffffffffffffffffffffffffffffffffff1684604051612f4490614ade565b60006040518083038185875af1925050503d8060008114612f81576040519150601f19603f3d011682016040523d82523d6000602084013e612f86565b606091505b5050905080612fca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fc190614b3f565b60405180910390fd5b7f81f40cfa7691027044b117aa50764b33eaa2223ca9f761d5ff1c316a33d65ad284604051612ff991906137fa565b60405180910390a150505061300c6134df565b50565b6201518081565b670de0b6b3a764000081565b60026000540361305e576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600081905550565b60006008600083815260200190815260200160002054905060006001600780549050613094919061456a565b90508082146130fd576000600782815481106130b3576130b2614bcb565b5b9060005260206000200154905080600784815481106130d5576130d4614bcb565b5b9060005260206000200181905550826008600083815260200190815260200160002081905550505b600780548061310f5761310e614eb8565b5b600190038181906000526020600020016000905590556008600084815260200190815260200160002060009055505050565b6000600260008381526020019081526020016000209050600073d458261e832415cfd3bae5e416fdf3230ce6f13473ffffffffffffffffffffffffffffffffffffffff166382ee990c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131dd9190614efc565b9050600073d458261e832415cfd3bae5e416fdf3230ce6f13473ffffffffffffffffffffffffffffffffffffffff16637ab2ac368360006040518363ffffffff1660e01b8152600401613231929190614f74565b602060405180830381865afa15801561324e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132729190614fe5565b6fffffffffffffffffffffffffffffffff16905060006132906122e3565b9050808261329e91906141fa565b4710156132e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132d79061505e565b60405180910390fd5b60028460090160006101000a81548160ff02191690836006811115613308576133076138cf565b5b0217905550428460080181905550600073d458261e832415cfd3bae5e416fdf3230ce6f13473ffffffffffffffffffffffffffffffffffffffff1663f77b45e18486894260405160200161335d92919061509f565b6040516020818303038152906040528051906020012060006040518563ffffffff1660e01b8152600401613393939291906150da565b60206040518083038185885af11580156133b1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906133d69190615126565b905085600660008367ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002081905550857fb9560bd3e25a95a3fcca6c0f21c6e8d9d07165bb54ae84dd553e21bbd94ce262826040516134349190615162565b60405180910390a2505050505050565b60006002600083815260200190815260200160002090506203f4804261346a91906141fa565b816006018190555060048160090160006101000a81548160ff0219169083600681111561349a576134996138cf565b5b0217905550817f9d89339efaabc79993cee28742c00a934cf47c83f7f84ded158cf05eb204a4ba82600601546040516134d391906137fa565b60405180910390a25050565b6001600081905550565b600073d458261e832415cfd3bae5e416fdf3230ce6f134905090565b73d458261e832415cfd3bae5e416fdf3230ce6f13473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161357e906151c9565b60405180910390fd5b6000600660008567ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020549050600081036135f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135ed90615235565b60405180910390fd5b613603818360001c613609565b50505050565b600060026000848152602001908152602001600020905060026006811115613634576136336138cf565b5b8160090160009054906101000a900460ff166006811115613658576136576138cf565b5b14613698576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161368f90614067565b60405180910390fd5b60008160040154836136aa9190615255565b905060006003600086815260200190815260200160002082815481106136d3576136d2614bcb565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808360050160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506203f4804261375291906141fa565b836006018190555060038360090160006101000a81548160ff02191690836006811115613782576137816138cf565b5b02179055508073ffffffffffffffffffffffffffffffffffffffff16857ffee5b04775e1cd2311ed22cd00f5d2403aff38ff6f71d6d393f51854ed6bc98685600301546040516137d291906137fa565b60405180910390a35050505050565b6000819050919050565b6137f4816137e1565b82525050565b600060208201905061380f60008301846137eb565b92915050565b600080fd5b613823816137e1565b811461382e57600080fd5b50565b6000813590506138408161381a565b92915050565b60006020828403121561385c5761385b613815565b5b600061386a84828501613831565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061389e82613873565b9050919050565b6138ae81613893565b82525050565b60008115159050919050565b6138c9816138b4565b82525050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6007811061390f5761390e6138cf565b5b50565b6000819050613920826138fe565b919050565b600061393082613912565b9050919050565b61394081613925565b82525050565b60006101408201905061395c600083018d6137eb565b613969602083018c6137eb565b613976604083018b6137eb565b613983606083018a6137eb565b61399060808301896137eb565b61399d60a08301886138a5565b6139aa60c08301876138c0565b6139b760e08301866137eb565b6139c56101008301856137eb565b6139d3610120830184613937565b9b9a5050505050505050505050565b60006020820190506139f760008301846138a5565b92915050565b613a0681613893565b8114613a1157600080fd5b50565b600081359050613a23816139fd565b92915050565b60008060408385031215613a4057613a3f613815565b5b6000613a4e85828601613831565b9250506020613a5f85828601613a14565b9150509250929050565b6000608082019050613a7e60008301876138c0565b613a8b60208301866138c0565b613a9860408301856138c0565b613aa560608301846137eb565b95945050505050565b60008060008060808587031215613ac857613ac7613815565b5b6000613ad687828801613831565b9450506020613ae787828801613831565b9350506040613af887828801613831565b9250506060613b0987828801613831565b91505092959194509250565b6000602082019050613b2a60008301846138c0565b92915050565b600067ffffffffffffffff82169050919050565b613b4d81613b30565b8114613b5857600080fd5b50565b600081359050613b6a81613b44565b92915050565b6000819050919050565b613b8381613b70565b8114613b8e57600080fd5b50565b600081359050613ba081613b7a565b92915050565b600080600060608486031215613bbf57613bbe613815565b5b6000613bcd86828701613b5b565b9350506020613bde86828701613a14565b9250506040613bef86828701613b91565b9150509250925092565b600061016082019050613c0f600083018e6137eb565b613c1c602083018d6137eb565b613c29604083018c6137eb565b613c36606083018b6137eb565b613c43608083018a6137eb565b613c5060a08301896138a5565b613c5d60c08301886138c0565b613c6a60e08301876137eb565b613c786101008301866137eb565b613c866101208301856137eb565b613c94610140830184613937565b9c9b505050505050505050505050565b600060208284031215613cba57613cb9613815565b5b6000613cc884828501613b5b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613d06816137e1565b82525050565b6000613d188383613cfd565b60208301905092915050565b6000602082019050919050565b6000613d3c82613cd1565b613d468185613cdc565b9350613d5183613ced565b8060005b83811015613d82578151613d698882613d0c565b9750613d7483613d24565b925050600181019050613d55565b5085935050505092915050565b60006020820190508181036000830152613da98184613d31565b905092915050565b6000819050919050565b6000613dd6613dd1613dcc84613873565b613db1565b613873565b9050919050565b6000613de882613dbb565b9050919050565b6000613dfa82613ddd565b9050919050565b613e0a81613def565b82525050565b6000602082019050613e256000830184613e01565b92915050565b60008060408385031215613e4257613e41613815565b5b6000613e5085828601613831565b9250506020613e6185828601613831565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613ea081613893565b82525050565b6000613eb28383613e97565b60208301905092915050565b6000602082019050919050565b6000613ed682613e6b565b613ee08185613e76565b9350613eeb83613e87565b8060005b83811015613f1c578151613f038882613ea6565b9750613f0e83613ebe565b925050600181019050613eef565b5085935050505092915050565b60006020820190508181036000830152613f438184613ecb565b905092915050565b600060a082019050613f6060008301886138c0565b613f6d60208301876137eb565b613f7a60408301866137eb565b613f8760608301856137eb565b613f9460808301846138c0565b9695505050505050565b600082825260208201905092915050565b7f4e6f742061646d696e0000000000000000000000000000000000000000000000600082015250565b6000613fe5600983613f9e565b9150613ff082613faf565b602082019050919050565b6000602082019050818103600083015261401481613fd8565b9050919050565b7f496e76616c696420737461746500000000000000000000000000000000000000600082015250565b6000614051600d83613f9e565b915061405c8261401b565b602082019050919050565b6000602082019050818103600083015261408081614044565b9050919050565b7f526166666c65206e6f7420656e64656400000000000000000000000000000000600082015250565b60006140bd601083613f9e565b91506140c882614087565b602082019050919050565b600060208201905081810360008301526140ec816140b0565b9050919050565b7f4e6f207061727469636970616e74730000000000000000000000000000000000600082015250565b6000614129600f83613f9e565b9150614134826140f3565b602082019050919050565b600060208201905081810360008301526141588161411c565b9050919050565b7f4e6f742070656e64696e67205652460000000000000000000000000000000000600082015250565b6000614195600f83613f9e565b91506141a08261415f565b602082019050919050565b600060208201905081810360008301526141c481614188565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614205826137e1565b9150614210836137e1565b9250828201905080821115614228576142276141cb565b5b92915050565b7f5652462074696d656f7574206e6f742072656163686564000000000000000000600082015250565b6000614264601783613f9e565b915061426f8261422e565b602082019050919050565b6000602082019050818103600083015261429381614257565b9050919050565b7f5652462074696d656f7574000000000000000000000000000000000000000000600082015250565b60006142d0600b83613f9e565b91506142db8261429a565b602082019050919050565b600060208201905081810360008301526142ff816142c3565b9050919050565b7f496e76616c69642074696d652072616e67650000000000000000000000000000600082015250565b600061433c601283613f9e565b915061434782614306565b602082019050919050565b6000602082019050818103600083015261436b8161432f565b9050919050565b7f53746172742074696d65206d7573742062652066757475726500000000000000600082015250565b60006143a8601983613f9e565b91506143b382614372565b602082019050919050565b600060208201905081810360008301526143d78161439b565b9050919050565b7f5468726573686f6c64206d757374206265203e20300000000000000000000000600082015250565b6000614414601583613f9e565b915061441f826143de565b602082019050919050565b6000602082019050818103600083015261444381614407565b9050919050565b7f526577617264206d757374206265203e20300000000000000000000000000000600082015250565b6000614480601283613f9e565b915061448b8261444a565b602082019050919050565b600060208201905081810360008301526144af81614473565b9050919050565b7f496e73756666696369656e742062616c616e6365000000000000000000000000600082015250565b60006144ec601483613f9e565b91506144f7826144b6565b602082019050919050565b6000602082019050818103600083015261451b816144df565b9050919050565b600061452d826137e1565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361455f5761455e6141cb565b5b600182019050919050565b6000614575826137e1565b9150614580836137e1565b9250828203905081811115614598576145976141cb565b5b92915050565b60006080820190506145b360008301876137eb565b6145c060208301866137eb565b6145cd60408301856137eb565b6145da60608301846137eb565b95945050505050565b7f526166666c65206e6f74206f70656e0000000000000000000000000000000000600082015250565b6000614619600f83613f9e565b9150614624826145e3565b602082019050919050565b600060208201905081810360008301526146488161460c565b9050919050565b7f526166666c65206e6f7420737461727465640000000000000000000000000000600082015250565b6000614685601283613f9e565b91506146908261464f565b602082019050919050565b600060208201905081810360008301526146b481614678565b9050919050565b7f526166666c6520656e6465640000000000000000000000000000000000000000600082015250565b60006146f1600c83613f9e565b91506146fc826146bb565b602082019050919050565b60006020820190508181036000830152614720816146e4565b9050919050565b7f4d7573742073656e642065786163746c792031204d4f4e000000000000000000600082015250565b600061475d601783613f9e565b915061476882614727565b602082019050919050565b6000602082019050818103600083015261478c81614750565b9050919050565b7f416c7265616479206a6f696e6564000000000000000000000000000000000000600082015250565b60006147c9600e83613f9e565b91506147d482614793565b602082019050919050565b600060208201905081810360008301526147f8816147bc565b9050919050565b7f456e74726f70792061646472657373206e6f7420736574000000000000000000600082015250565b6000614835601783613f9e565b9150614840826147ff565b602082019050919050565b6000602082019050818103600083015261486481614828565b9050919050565b7f4f6e6c7920456e74726f70792063616e2063616c6c20746869732066756e637460008201527f696f6e0000000000000000000000000000000000000000000000000000000000602082015250565b60006148c7602383613f9e565b91506148d28261486b565b604082019050919050565b600060208201905081810360008301526148f6816148ba565b9050919050565b7f526566756e6473206e6f7420656e61626c656400000000000000000000000000600082015250565b6000614933601383613f9e565b915061493e826148fd565b602082019050919050565b6000602082019050818103600083015261496281614926565b9050919050565b7f446964206e6f7420706172746963697061746500000000000000000000000000600082015250565b600061499f601383613f9e565b91506149aa82614969565b602082019050919050565b600060208201905081810360008301526149ce81614992565b9050919050565b7f416c726561647920636c61696d65640000000000000000000000000000000000600082015250565b6000614a0b600f83613f9e565b9150614a16826149d5565b602082019050919050565b60006020820190508181036000830152614a3a816149fe565b9050919050565b7f436c61696d2077696e646f772065787069726564000000000000000000000000600082015250565b6000614a77601483613f9e565b9150614a8282614a41565b602082019050919050565b60006020820190508181036000830152614aa681614a6a565b9050919050565b600081905092915050565b50565b6000614ac8600083614aad565b9150614ad382614ab8565b600082019050919050565b6000614ae982614abb565b9150819050919050565b7f5472616e73666572206661696c65640000000000000000000000000000000000600082015250565b6000614b29600f83613f9e565b9150614b3482614af3565b602082019050919050565b60006020820190508181036000830152614b5881614b1c565b9050919050565b7f4d7573742073656e64204d4f4e00000000000000000000000000000000000000600082015250565b6000614b95600d83613f9e565b9150614ba082614b5f565b602082019050919050565b60006020820190508181036000830152614bc481614b88565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000614c05826137e1565b9150614c10836137e1565b9250828202614c1e816137e1565b91508282048414831517614c3557614c346141cb565b5b5092915050565b7f57696e6e6572206e6f742073656c656374656400000000000000000000000000600082015250565b6000614c72601383613f9e565b9150614c7d82614c3c565b602082019050919050565b60006020820190508181036000830152614ca181614c65565b9050919050565b7f4e6f74207468652077696e6e6572000000000000000000000000000000000000600082015250565b6000614cde600e83613f9e565b9150614ce982614ca8565b602082019050919050565b60006020820190508181036000830152614d0d81614cd1565b9050919050565b7f43616e6e6f74206d61726b20636f6d706c657465640000000000000000000000600082015250565b6000614d4a601583613f9e565b9150614d5582614d14565b602082019050919050565b60006020820190508181036000830152614d7981614d3d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614dba826137e1565b9150614dc5836137e1565b925082614dd557614dd4614d80565b5b828204905092915050565b7f416d6f756e74206d757374206265203e20300000000000000000000000000000600082015250565b6000614e16601283613f9e565b9150614e2182614de0565b602082019050919050565b60006020820190508181036000830152614e4581614e09565b9050919050565b7f4578636565647320776974686472617761626c6520616d6f756e740000000000600082015250565b6000614e82601b83613f9e565b9150614e8d82614e4c565b602082019050919050565b60006020820190508181036000830152614eb181614e75565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600081519050614ef6816139fd565b92915050565b600060208284031215614f1257614f11613815565b5b6000614f2084828501614ee7565b91505092915050565b6000819050919050565b600063ffffffff82169050919050565b6000614f5e614f59614f5484614f29565b613db1565b614f33565b9050919050565b614f6e81614f43565b82525050565b6000604082019050614f8960008301856138a5565b614f966020830184614f65565b9392505050565b60006fffffffffffffffffffffffffffffffff82169050919050565b614fc281614f9d565b8114614fcd57600080fd5b50565b600081519050614fdf81614fb9565b92915050565b600060208284031215614ffb57614ffa613815565b5b600061500984828501614fd0565b91505092915050565b7f496e73756666696369656e742062616c616e636520666f722056524620666565600082015250565b6000615048602083613f9e565b915061505382615012565b602082019050919050565b600060208201905081810360008301526150778161503b565b9050919050565b6000819050919050565b615099615094826137e1565b61507e565b82525050565b60006150ab8285615088565b6020820191506150bb8284615088565b6020820191508190509392505050565b6150d481613b70565b82525050565b60006060820190506150ef60008301866138a5565b6150fc60208301856150cb565b6151096040830184614f65565b949350505050565b60008151905061512081613b44565b92915050565b60006020828403121561513c5761513b613815565b5b600061514a84828501615111565b91505092915050565b61515c81613b30565b82525050565b60006020820190506151776000830184615153565b92915050565b7f556e617574686f72697a65640000000000000000000000000000000000000000600082015250565b60006151b3600c83613f9e565b91506151be8261517d565b602082019050919050565b600060208201905081810360008301526151e2816151a6565b9050919050565b7f556e6b6e6f776e20726571756573740000000000000000000000000000000000600082015250565b600061521f600f83613f9e565b915061522a826151e9565b602082019050919050565b6000602082019050818103600083015261524e81615212565b9050919050565b6000615260826137e1565b915061526b836137e1565b92508261527b5761527a614d80565b5b82820690509291505056fea26469706673582212201348102d64481bb5e2cef4775050246d5d8e6a6ec68ff01308c8a53a241fdbe364736f6c634300081c0033

Deployed Bytecode

0x6080604052600436106102085760003560e01c8063857f675d11610118578063b1ddd82a116100a0578063d1cfcd0d1161006f578063d1cfcd0d1461082e578063dad717741461086f578063effbe39a1461089a578063f4d1c5f6146108c3578063f6d361cc146108ee5761025d565b8063b1ddd82a1461074e578063c04b11f01461078b578063c1e3bd3e146107c8578063c7d91d27146108055761025d565b80639eb94824116100e75780639eb94824146106675780639f34fc8014610692578063ae169a50146106bd578063afb218f5146106e6578063b154afc3146107115761025d565b8063857f675d1461059757806390be10cc146105c25780639827ba57146105ed5780639c5b281d1461062a5761025d565b8063485de6ff1161019b578063681947191161016a57806368194719146104ab578063758d9b89146104e85780637befbefc146105255780637f200416146105625780638458e3e41461056c5761025d565b8063485de6ff146103d557806352a5f1f8146104125780635b7baf641461043b5780635d4bc0ce146104645761025d565b80632c2aa24e116101d75780632c2aa24e146103255780632d2c55651461036557806339510c85146103905780634758eca9146103b95761025d565b8063186a646a146102625780632192e4fa1461028b57806327d7e46d146102b45780632a0acc6a146102fa5761025d565b3661025d573373ffffffffffffffffffffffffffffffffffffffff167f0b65a8269cbde15c758c61aa6aca57ed9f9598dc5667cbd823244c449f5e572d3460405161025391906137fa565b60405180910390a2005b600080fd5b34801561026e57600080fd5b5061028960048036038101906102849190613846565b610919565b005b34801561029757600080fd5b506102b260048036038101906102ad9190613846565b610b96565b005b3480156102c057600080fd5b506102db60048036038101906102d69190613846565b610d89565b6040516102f19a99989796959493929190613946565b60405180910390f35b34801561030657600080fd5b5061030f610e3d565b60405161031c91906139e2565b60405180910390f35b34801561033157600080fd5b5061034c60048036038101906103479190613a29565b610e55565b60405161035c9493929190613a69565b60405180910390f35b34801561037157600080fd5b5061037a6110c5565b60405161038791906139e2565b60405180910390f35b34801561039c57600080fd5b506103b760048036038101906103b29190613aae565b6110dd565b005b6103d360048036038101906103ce9190613846565b6114ed565b005b3480156103e157600080fd5b506103fc60048036038101906103f79190613a29565b6118fa565b6040516104099190613b15565b60405180910390f35b34801561041e57600080fd5b5061043960048036038101906104349190613ba6565b6119da565b005b34801561044757600080fd5b50610462600480360381019061045d9190613846565b611ad4565b005b34801561047057600080fd5b5061048b60048036038101906104869190613846565b611f27565b6040516104a29b9a99989796959493929190613bf9565b60405180910390f35b3480156104b757600080fd5b506104d260048036038101906104cd9190613a29565b611fbb565b6040516104df9190613b15565b60405180910390f35b3480156104f457600080fd5b5061050f600480360381019061050a9190613a29565b611fea565b60405161051c9190613b15565b60405180910390f35b34801561053157600080fd5b5061054c60048036038101906105479190613a29565b612052565b6040516105599190613b15565b60405180910390f35b61056a6121c8565b005b34801561057857600080fd5b506105816122dd565b60405161058e91906137fa565b60405180910390f35b3480156105a357600080fd5b506105ac6122e3565b6040516105b991906137fa565b60405180910390f35b3480156105ce57600080fd5b506105d7612571565b6040516105e491906137fa565b60405180910390f35b3480156105f957600080fd5b50610614600480360381019061060f9190613846565b61258b565b60405161062191906137fa565b60405180910390f35b34801561063657600080fd5b50610651600480360381019061064c9190613ca4565b6125af565b60405161065e91906137fa565b60405180910390f35b34801561067357600080fd5b5061067c6125c7565b6040516106899190613d8f565b60405180910390f35b34801561069e57600080fd5b506106a761261f565b6040516106b491906137fa565b60405180910390f35b3480156106c957600080fd5b506106e460048036038101906106df9190613846565b612626565b005b3480156106f257600080fd5b506106fb612978565b6040516107089190613e10565b60405180910390f35b34801561071d57600080fd5b5061073860048036038101906107339190613a29565b612990565b6040516107459190613b15565b60405180910390f35b34801561075a57600080fd5b5061077560048036038101906107709190613e2b565b6129bf565b60405161078291906139e2565b60405180910390f35b34801561079757600080fd5b506107b260048036038101906107ad9190613846565b612a0d565b6040516107bf91906137fa565b60405180910390f35b3480156107d457600080fd5b506107ef60048036038101906107ea9190613846565b612a25565b6040516107fc9190613f29565b60405180910390f35b34801561081157600080fd5b5061082c60048036038101906108279190613846565b612ac6565b005b34801561083a57600080fd5b5061085560048036038101906108509190613846565b612cfc565b604051610866959493929190613f4b565b60405180910390f35b34801561087b57600080fd5b50610884612dd1565b60405161089191906137fa565b60405180910390f35b3480156108a657600080fd5b506108c160048036038101906108bc9190613846565b612dde565b005b3480156108cf57600080fd5b506108d861300f565b6040516108e591906137fa565b60405180910390f35b3480156108fa57600080fd5b50610903613016565b60405161091091906137fa565b60405180910390f35b7314d5aa304af9c1aeff1f37375f85ba0cbfb6c10473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461099b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099290613ffb565b60405180910390fd5b6109a3613022565b6000600260008381526020019081526020016000209050600160068111156109ce576109cd6138cf565b5b8160090160009054906101000a900460ff1660068111156109f2576109f16138cf565b5b1480610a33575060006006811115610a0d57610a0c6138cf565b5b8160090160009054906101000a900460ff166006811115610a3157610a306138cf565b5b145b610a72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6990614067565b60405180910390fd5b80600101544211610ab8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aaf906140d3565b60405180910390fd5b6000816004015403610b625760058160090160006101000a81548160ff02191690836006811115610aec57610aeb6138cf565b5b0217905550610afa82613068565b817f4b065d94bb5f805836b9aefd08a7b4388cfdd8d346a56ef0a4a547dbca8b8f1f604051610b289061413f565b60405180910390a2817f1e15dbf45ae533c182513b50c5b94530ab41942881a0bb1dc4206313d8b4115960405160405180910390a2610b8a565b8060020154816004015410610b7f57610b7a82613141565b610b89565b610b8882613444565b5b5b50610b936134df565b50565b7314d5aa304af9c1aeff1f37375f85ba0cbfb6c10473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0f90613ffb565b60405180910390fd5b610c20613022565b600060026000838152602001908152602001600020905060026006811115610c4b57610c4a6138cf565b5b8160090160009054906101000a900460ff166006811115610c6f57610c6e6138cf565b5b14610caf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca6906141ab565b60405180910390fd5b620151808160080154610cc291906141fa565b4211610d03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cfa9061427a565b60405180910390fd5b60068160090160006101000a81548160ff02191690836006811115610d2b57610d2a6138cf565b5b02179055506203f48042610d3f91906141fa565b8160060181905550817f4b065d94bb5f805836b9aefd08a7b4388cfdd8d346a56ef0a4a547dbca8b8f1f604051610d75906142e6565b60405180910390a250610d866134df565b50565b6000806000806000806000806000806000600260008d81526020019081526020016000209050806000015481600101548260020154836003015484600401548560050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660050160149054906101000a900460ff16876006015488600701548960090160009054906101000a900460ff169a509a509a509a509a509a509a509a509a509a50509193959799509193959799565b7314d5aa304af9c1aeff1f37375f85ba0cbfb6c10481565b60008060008060006002600088815260200190815260200160002090508573ffffffffffffffffffffffffffffffffffffffff168160050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614945060036006811115610edb57610eda6138cf565b5b8160090160009054906101000a900460ff166006811115610eff57610efe6138cf565b5b148015610f095750845b8015610f2457508060050160149054906101000a900460ff16155b8015610f34575080600601544211155b935060046006811115610f4a57610f496138cf565b5b8160090160009054906101000a900460ff166006811115610f6e57610f6d6138cf565b5b1480610fae5750600680811115610f8857610f876138cf565b5b8160090160009054906101000a900460ff166006811115610fac57610fab6138cf565b5b145b801561101457506004600088815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b801561107b57506005600088815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b801561108b575080600601544211155b9250831561109f57806003015491506110bb565b82156110b557670de0b6b3a764000091506110ba565b600091505b5b5092959194509250565b736779387e262e3ec8c81f62dcd3b2348931b5254d81565b7314d5aa304af9c1aeff1f37375f85ba0cbfb6c10473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461115f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161115690613ffb565b60405180910390fd5b8284106111a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119890614352565b60405180910390fd5b4284116111e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111da906143be565b60405180910390fd5b60008211611226576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121d9061442a565b60405180910390fd5b60008111611269576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126090614496565b60405180910390fd5b6112716122e3565b8161127c91906141fa565b4710156112be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b590614502565b60405180910390fd5b6000600160008154809291906112d390614522565b91905055905060405180610160016040528086815260200185815260200184815260200183815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160001515815260200160008152602001600081526020016000815260200160006006811115611353576113526138cf565b5b81525060026000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060c08201518160050160146101000a81548160ff02191690831515021790555060e08201518160060155610100820151816007015561012082015181600801556101408201518160090160006101000a81548160ff0219169083600681111561144e5761144d6138cf565b5b021790555090505060078190806001815401808255809150506001900390600052602060002001600090919091909150556001600780549050611491919061456a565b6008600083815260200190815260200160002081905550807ffcc13aaaf4660281e2662ae91069e5f95cc7863d25a6a68e620806a99354fa1a868686866040516114de949392919061459e565b60405180910390a25050505050565b6114f5613022565b6000600260008381526020019081526020016000209050600060068111156115205761151f6138cf565b5b8160090160009054906101000a900460ff166006811115611544576115436138cf565b5b148061158557506001600681111561155f5761155e6138cf565b5b8160090160009054906101000a900460ff166006811115611583576115826138cf565b5b145b6115c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bb9061462f565b60405180910390fd5b806000015442101561160b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116029061469b565b60405180910390fd5b80600101544210611651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164890614707565b60405180910390fd5b670de0b6b3a7640000341461169b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169290614773565b60405180910390fd5b6004600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611739576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611730906147df565b60405180910390fd5b6000600681111561174d5761174c6138cf565b5b8160090160009054906101000a900460ff166006811115611771576117706138cf565b5b036117a45760018160090160006101000a81548160ff0219169083600681111561179e5761179d6138cf565b5b02179055505b60016004600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060036000838152602001908152602001600020339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600401600081548092919061189690614522565b91905055503373ffffffffffffffffffffffffffffffffffffffff16827f338e0cd33c4e120afcd73f43f082fd8940ed67ac35180d278d2eb4f3ed51d92e83600401546040516118e691906137fa565b60405180910390a3506118f76134df565b50565b60008060026000858152602001908152602001600020905060036006811115611926576119256138cf565b5b8160090160009054906101000a900460ff16600681111561194a576119496138cf565b5b1480156119a657508273ffffffffffffffffffffffffffffffffffffffff168160050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b80156119c157508060050160149054906101000a900460ff16155b80156119d1575080600601544211155b91505092915050565b60006119e46134e9565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611a55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4c9061484b565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611ac3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aba906148dd565b60405180910390fd5b611ace848484613505565b50505050565b611adc613022565b600060026000838152602001908152602001600020905060046006811115611b0757611b066138cf565b5b8160090160009054906101000a900460ff166006811115611b2b57611b2a6138cf565b5b1480611b6b5750600680811115611b4557611b446138cf565b5b8160090160009054906101000a900460ff166006811115611b6957611b686138cf565b5b145b611baa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba190614949565b60405180910390fd5b6004600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611c47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3e906149b5565b60405180910390fd5b6005600083815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611ce5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cdc90614a21565b60405180910390fd5b8060060154421115611d2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d2390614a8d565b60405180910390fd5b60016005600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550806007016000815480929190611daa90614522565b91905055508060040154816007015403611e225760058160090160006101000a81548160ff02191690836006811115611de657611de56138cf565b5b0217905550611df482613068565b817f1e15dbf45ae533c182513b50c5b94530ab41942881a0bb1dc4206313d8b4115960405160405180910390a25b60003373ffffffffffffffffffffffffffffffffffffffff16670de0b6b3a7640000604051611e5090614ade565b60006040518083038185875af1925050503d8060008114611e8d576040519150601f19603f3d011682016040523d82523d6000602084013e611e92565b606091505b5050905080611ed6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ecd90614b3f565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16837fd86f3d2d747d5d831df461fda7bf64b7d9d57ff4b8b3fe58836776cf90a6bda560405160405180910390a35050611f246134df565b50565b60026020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060050160149054906101000a900460ff16908060060154908060070154908060080154908060090160009054906101000a900460ff1690508b565b60046020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b60006004600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000806002600085815260200190815260200160002090506004600681111561207e5761207d6138cf565b5b8160090160009054906101000a900460ff1660068111156120a2576120a16138cf565b5b14806120e257506006808111156120bc576120bb6138cf565b5b8160090160009054906101000a900460ff1660068111156120e0576120df6138cf565b5b145b801561214857506004600085815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b80156121af57506005600085815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b80156121bf575080600601544211155b91505092915050565b7314d5aa304af9c1aeff1f37375f85ba0cbfb6c10473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461224a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161224190613ffb565b60405180910390fd5b6000341161228d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228490614bab565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f0b65a8269cbde15c758c61aa6aca57ed9f9598dc5667cbd823244c449f5e572d346040516122d391906137fa565b60405180910390a2565b60015481565b600080600090505b60078054905081101561256d5760006007828154811061230e5761230d614bcb565b5b90600052602060002001549050600060026000838152602001908152602001600020905060006006811115612346576123456138cf565b5b8160090160009054906101000a900460ff16600681111561236a576123696138cf565b5b14806123ab575060016006811115612385576123846138cf565b5b8160090160009054906101000a900460ff1660068111156123a9576123a86138cf565b5b145b156123c7578060030154846123c091906141fa565b935061255e565b600260068111156123db576123da6138cf565b5b8160090160009054906101000a900460ff1660068111156123ff576123fe6138cf565b5b0361241b5780600301548461241491906141fa565b935061255d565b6003600681111561242f5761242e6138cf565b5b8160090160009054906101000a900460ff166006811115612453576124526138cf565b5b14801561246f57508060050160149054906101000a900460ff16155b1561249757806006015442116124925780600301548461248f91906141fa565b93505b61255c565b600460068111156124ab576124aa6138cf565b5b8160090160009054906101000a900460ff1660068111156124cf576124ce6138cf565b5b148061250f57506006808111156124e9576124e86138cf565b5b8160090160009054906101000a900460ff16600681111561250d5761250c6138cf565b5b145b1561255b578060060154421161255a57600081600701548260040154612535919061456a565b9050670de0b6b3a76400008161254b9190614bfa565b8561255691906141fa565b9450505b5b5b5b5b505080806001019150506122eb565b5090565b600061257b6122e3565b47612586919061456a565b905090565b6007818154811061259b57600080fd5b906000526020600020016000915090505481565b60066020528060005260406000206000915090505481565b6060600780548060200260200160405190810160405280929190818152602001828054801561261557602002820191906000526020600020905b815481526020019060010190808311612601575b5050505050905090565b6203f48081565b61262e613022565b600060026000838152602001908152602001600020905060036006811115612659576126586138cf565b5b8160090160009054906101000a900460ff16600681111561267d5761267c6138cf565b5b146126bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126b490614c88565b60405180910390fd5b8060050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461274f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161274690614cf4565b60405180910390fd5b8060050160149054906101000a900460ff16156127a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279890614a21565b60405180910390fd5b80600601544211156127e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127df90614a8d565b60405180910390fd5b60018160050160146101000a81548160ff02191690831515021790555060058160090160006101000a81548160ff0219169083600681111561282d5761282c6138cf565b5b021790555061283b82613068565b60003373ffffffffffffffffffffffffffffffffffffffff16826003015460405161286590614ade565b60006040518083038185875af1925050503d80600081146128a2576040519150601f19603f3d011682016040523d82523d6000602084013e6128a7565b606091505b50509050806128eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128e290614b3f565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16837f24b5efa61dd1cfc659205a97fb8ed868f3cb8c81922bab2b96423e5de1de2cb7846003015460405161293691906137fa565b60405180910390a3827f1e15dbf45ae533c182513b50c5b94530ab41942881a0bb1dc4206313d8b4115960405160405180910390a250506129756134df565b50565b73d458261e832415cfd3bae5e416fdf3230ce6f13481565b60056020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b600360205281600052604060002081815481106129db57600080fd5b906000526020600020016000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60086020528060005260406000206000915090505481565b606060036000838152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015612aba57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311612a70575b50505050509050919050565b7314d5aa304af9c1aeff1f37375f85ba0cbfb6c10473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612b48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b3f90613ffb565b60405180910390fd5b6000600260008381526020019081526020016000209050600060036006811115612b7557612b746138cf565b5b8260090160009054906101000a900460ff166006811115612b9957612b986138cf565b5b148015612ba95750816006015442115b9050600060046006811115612bc157612bc06138cf565b5b8360090160009054906101000a900460ff166006811115612be557612be46138cf565b5b148015612bf55750826006015442115b90506000600680811115612c0c57612c0b6138cf565b5b8460090160009054906101000a900460ff166006811115612c3057612c2f6138cf565b5b148015612c405750836006015442115b90508280612c4b5750815b80612c535750805b612c92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8990614d60565b60405180910390fd5b60058460090160006101000a81548160ff02191690836006811115612cba57612cb96138cf565b5b0217905550612cc885613068565b847f1e15dbf45ae533c182513b50c5b94530ab41942881a0bb1dc4206313d8b4115960405160405180910390a25050505050565b60008060008060008060026000888152602001908152602001600020905080600201548160040154101595506000816002015411612d3b576000612d5c565b806002015460648260040154612d519190614bfa565b612d5b9190614daf565b5b945085612d8057670de0b6b3a76400008160040154612d7b9190614bfa565b612d83565b60005b93508060070154925060056006811115612da057612d9f6138cf565b5b8160090160009054906101000a900460ff166006811115612dc457612dc36138cf565b5b1491505091939590929450565b6000600780549050905090565b7314d5aa304af9c1aeff1f37375f85ba0cbfb6c10473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612e60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e5790613ffb565b60405180910390fd5b612e68613022565b60008111612eab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ea290614e2c565b60405180910390fd5b6000612eb56122e3565b905060008147612ec5919061456a565b905080831115612f0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f0190614e98565b60405180910390fd5b6000736779387e262e3ec8c81f62dcd3b2348931b5254d73ffffffffffffffffffffffffffffffffffffffff1684604051612f4490614ade565b60006040518083038185875af1925050503d8060008114612f81576040519150601f19603f3d011682016040523d82523d6000602084013e612f86565b606091505b5050905080612fca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fc190614b3f565b60405180910390fd5b7f81f40cfa7691027044b117aa50764b33eaa2223ca9f761d5ff1c316a33d65ad284604051612ff991906137fa565b60405180910390a150505061300c6134df565b50565b6201518081565b670de0b6b3a764000081565b60026000540361305e576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600081905550565b60006008600083815260200190815260200160002054905060006001600780549050613094919061456a565b90508082146130fd576000600782815481106130b3576130b2614bcb565b5b9060005260206000200154905080600784815481106130d5576130d4614bcb565b5b9060005260206000200181905550826008600083815260200190815260200160002081905550505b600780548061310f5761310e614eb8565b5b600190038181906000526020600020016000905590556008600084815260200190815260200160002060009055505050565b6000600260008381526020019081526020016000209050600073d458261e832415cfd3bae5e416fdf3230ce6f13473ffffffffffffffffffffffffffffffffffffffff166382ee990c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131dd9190614efc565b9050600073d458261e832415cfd3bae5e416fdf3230ce6f13473ffffffffffffffffffffffffffffffffffffffff16637ab2ac368360006040518363ffffffff1660e01b8152600401613231929190614f74565b602060405180830381865afa15801561324e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132729190614fe5565b6fffffffffffffffffffffffffffffffff16905060006132906122e3565b9050808261329e91906141fa565b4710156132e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132d79061505e565b60405180910390fd5b60028460090160006101000a81548160ff02191690836006811115613308576133076138cf565b5b0217905550428460080181905550600073d458261e832415cfd3bae5e416fdf3230ce6f13473ffffffffffffffffffffffffffffffffffffffff1663f77b45e18486894260405160200161335d92919061509f565b6040516020818303038152906040528051906020012060006040518563ffffffff1660e01b8152600401613393939291906150da565b60206040518083038185885af11580156133b1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906133d69190615126565b905085600660008367ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002081905550857fb9560bd3e25a95a3fcca6c0f21c6e8d9d07165bb54ae84dd553e21bbd94ce262826040516134349190615162565b60405180910390a2505050505050565b60006002600083815260200190815260200160002090506203f4804261346a91906141fa565b816006018190555060048160090160006101000a81548160ff0219169083600681111561349a576134996138cf565b5b0217905550817f9d89339efaabc79993cee28742c00a934cf47c83f7f84ded158cf05eb204a4ba82600601546040516134d391906137fa565b60405180910390a25050565b6001600081905550565b600073d458261e832415cfd3bae5e416fdf3230ce6f134905090565b73d458261e832415cfd3bae5e416fdf3230ce6f13473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161357e906151c9565b60405180910390fd5b6000600660008567ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020549050600081036135f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135ed90615235565b60405180910390fd5b613603818360001c613609565b50505050565b600060026000848152602001908152602001600020905060026006811115613634576136336138cf565b5b8160090160009054906101000a900460ff166006811115613658576136576138cf565b5b14613698576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161368f90614067565b60405180910390fd5b60008160040154836136aa9190615255565b905060006003600086815260200190815260200160002082815481106136d3576136d2614bcb565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050808360050160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506203f4804261375291906141fa565b836006018190555060038360090160006101000a81548160ff02191690836006811115613782576137816138cf565b5b02179055508073ffffffffffffffffffffffffffffffffffffffff16857ffee5b04775e1cd2311ed22cd00f5d2403aff38ff6f71d6d393f51854ed6bc98685600301546040516137d291906137fa565b60405180910390a35050505050565b6000819050919050565b6137f4816137e1565b82525050565b600060208201905061380f60008301846137eb565b92915050565b600080fd5b613823816137e1565b811461382e57600080fd5b50565b6000813590506138408161381a565b92915050565b60006020828403121561385c5761385b613815565b5b600061386a84828501613831565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061389e82613873565b9050919050565b6138ae81613893565b82525050565b60008115159050919050565b6138c9816138b4565b82525050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6007811061390f5761390e6138cf565b5b50565b6000819050613920826138fe565b919050565b600061393082613912565b9050919050565b61394081613925565b82525050565b60006101408201905061395c600083018d6137eb565b613969602083018c6137eb565b613976604083018b6137eb565b613983606083018a6137eb565b61399060808301896137eb565b61399d60a08301886138a5565b6139aa60c08301876138c0565b6139b760e08301866137eb565b6139c56101008301856137eb565b6139d3610120830184613937565b9b9a5050505050505050505050565b60006020820190506139f760008301846138a5565b92915050565b613a0681613893565b8114613a1157600080fd5b50565b600081359050613a23816139fd565b92915050565b60008060408385031215613a4057613a3f613815565b5b6000613a4e85828601613831565b9250506020613a5f85828601613a14565b9150509250929050565b6000608082019050613a7e60008301876138c0565b613a8b60208301866138c0565b613a9860408301856138c0565b613aa560608301846137eb565b95945050505050565b60008060008060808587031215613ac857613ac7613815565b5b6000613ad687828801613831565b9450506020613ae787828801613831565b9350506040613af887828801613831565b9250506060613b0987828801613831565b91505092959194509250565b6000602082019050613b2a60008301846138c0565b92915050565b600067ffffffffffffffff82169050919050565b613b4d81613b30565b8114613b5857600080fd5b50565b600081359050613b6a81613b44565b92915050565b6000819050919050565b613b8381613b70565b8114613b8e57600080fd5b50565b600081359050613ba081613b7a565b92915050565b600080600060608486031215613bbf57613bbe613815565b5b6000613bcd86828701613b5b565b9350506020613bde86828701613a14565b9250506040613bef86828701613b91565b9150509250925092565b600061016082019050613c0f600083018e6137eb565b613c1c602083018d6137eb565b613c29604083018c6137eb565b613c36606083018b6137eb565b613c43608083018a6137eb565b613c5060a08301896138a5565b613c5d60c08301886138c0565b613c6a60e08301876137eb565b613c786101008301866137eb565b613c866101208301856137eb565b613c94610140830184613937565b9c9b505050505050505050505050565b600060208284031215613cba57613cb9613815565b5b6000613cc884828501613b5b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613d06816137e1565b82525050565b6000613d188383613cfd565b60208301905092915050565b6000602082019050919050565b6000613d3c82613cd1565b613d468185613cdc565b9350613d5183613ced565b8060005b83811015613d82578151613d698882613d0c565b9750613d7483613d24565b925050600181019050613d55565b5085935050505092915050565b60006020820190508181036000830152613da98184613d31565b905092915050565b6000819050919050565b6000613dd6613dd1613dcc84613873565b613db1565b613873565b9050919050565b6000613de882613dbb565b9050919050565b6000613dfa82613ddd565b9050919050565b613e0a81613def565b82525050565b6000602082019050613e256000830184613e01565b92915050565b60008060408385031215613e4257613e41613815565b5b6000613e5085828601613831565b9250506020613e6185828601613831565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613ea081613893565b82525050565b6000613eb28383613e97565b60208301905092915050565b6000602082019050919050565b6000613ed682613e6b565b613ee08185613e76565b9350613eeb83613e87565b8060005b83811015613f1c578151613f038882613ea6565b9750613f0e83613ebe565b925050600181019050613eef565b5085935050505092915050565b60006020820190508181036000830152613f438184613ecb565b905092915050565b600060a082019050613f6060008301886138c0565b613f6d60208301876137eb565b613f7a60408301866137eb565b613f8760608301856137eb565b613f9460808301846138c0565b9695505050505050565b600082825260208201905092915050565b7f4e6f742061646d696e0000000000000000000000000000000000000000000000600082015250565b6000613fe5600983613f9e565b9150613ff082613faf565b602082019050919050565b6000602082019050818103600083015261401481613fd8565b9050919050565b7f496e76616c696420737461746500000000000000000000000000000000000000600082015250565b6000614051600d83613f9e565b915061405c8261401b565b602082019050919050565b6000602082019050818103600083015261408081614044565b9050919050565b7f526166666c65206e6f7420656e64656400000000000000000000000000000000600082015250565b60006140bd601083613f9e565b91506140c882614087565b602082019050919050565b600060208201905081810360008301526140ec816140b0565b9050919050565b7f4e6f207061727469636970616e74730000000000000000000000000000000000600082015250565b6000614129600f83613f9e565b9150614134826140f3565b602082019050919050565b600060208201905081810360008301526141588161411c565b9050919050565b7f4e6f742070656e64696e67205652460000000000000000000000000000000000600082015250565b6000614195600f83613f9e565b91506141a08261415f565b602082019050919050565b600060208201905081810360008301526141c481614188565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614205826137e1565b9150614210836137e1565b9250828201905080821115614228576142276141cb565b5b92915050565b7f5652462074696d656f7574206e6f742072656163686564000000000000000000600082015250565b6000614264601783613f9e565b915061426f8261422e565b602082019050919050565b6000602082019050818103600083015261429381614257565b9050919050565b7f5652462074696d656f7574000000000000000000000000000000000000000000600082015250565b60006142d0600b83613f9e565b91506142db8261429a565b602082019050919050565b600060208201905081810360008301526142ff816142c3565b9050919050565b7f496e76616c69642074696d652072616e67650000000000000000000000000000600082015250565b600061433c601283613f9e565b915061434782614306565b602082019050919050565b6000602082019050818103600083015261436b8161432f565b9050919050565b7f53746172742074696d65206d7573742062652066757475726500000000000000600082015250565b60006143a8601983613f9e565b91506143b382614372565b602082019050919050565b600060208201905081810360008301526143d78161439b565b9050919050565b7f5468726573686f6c64206d757374206265203e20300000000000000000000000600082015250565b6000614414601583613f9e565b915061441f826143de565b602082019050919050565b6000602082019050818103600083015261444381614407565b9050919050565b7f526577617264206d757374206265203e20300000000000000000000000000000600082015250565b6000614480601283613f9e565b915061448b8261444a565b602082019050919050565b600060208201905081810360008301526144af81614473565b9050919050565b7f496e73756666696369656e742062616c616e6365000000000000000000000000600082015250565b60006144ec601483613f9e565b91506144f7826144b6565b602082019050919050565b6000602082019050818103600083015261451b816144df565b9050919050565b600061452d826137e1565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361455f5761455e6141cb565b5b600182019050919050565b6000614575826137e1565b9150614580836137e1565b9250828203905081811115614598576145976141cb565b5b92915050565b60006080820190506145b360008301876137eb565b6145c060208301866137eb565b6145cd60408301856137eb565b6145da60608301846137eb565b95945050505050565b7f526166666c65206e6f74206f70656e0000000000000000000000000000000000600082015250565b6000614619600f83613f9e565b9150614624826145e3565b602082019050919050565b600060208201905081810360008301526146488161460c565b9050919050565b7f526166666c65206e6f7420737461727465640000000000000000000000000000600082015250565b6000614685601283613f9e565b91506146908261464f565b602082019050919050565b600060208201905081810360008301526146b481614678565b9050919050565b7f526166666c6520656e6465640000000000000000000000000000000000000000600082015250565b60006146f1600c83613f9e565b91506146fc826146bb565b602082019050919050565b60006020820190508181036000830152614720816146e4565b9050919050565b7f4d7573742073656e642065786163746c792031204d4f4e000000000000000000600082015250565b600061475d601783613f9e565b915061476882614727565b602082019050919050565b6000602082019050818103600083015261478c81614750565b9050919050565b7f416c7265616479206a6f696e6564000000000000000000000000000000000000600082015250565b60006147c9600e83613f9e565b91506147d482614793565b602082019050919050565b600060208201905081810360008301526147f8816147bc565b9050919050565b7f456e74726f70792061646472657373206e6f7420736574000000000000000000600082015250565b6000614835601783613f9e565b9150614840826147ff565b602082019050919050565b6000602082019050818103600083015261486481614828565b9050919050565b7f4f6e6c7920456e74726f70792063616e2063616c6c20746869732066756e637460008201527f696f6e0000000000000000000000000000000000000000000000000000000000602082015250565b60006148c7602383613f9e565b91506148d28261486b565b604082019050919050565b600060208201905081810360008301526148f6816148ba565b9050919050565b7f526566756e6473206e6f7420656e61626c656400000000000000000000000000600082015250565b6000614933601383613f9e565b915061493e826148fd565b602082019050919050565b6000602082019050818103600083015261496281614926565b9050919050565b7f446964206e6f7420706172746963697061746500000000000000000000000000600082015250565b600061499f601383613f9e565b91506149aa82614969565b602082019050919050565b600060208201905081810360008301526149ce81614992565b9050919050565b7f416c726561647920636c61696d65640000000000000000000000000000000000600082015250565b6000614a0b600f83613f9e565b9150614a16826149d5565b602082019050919050565b60006020820190508181036000830152614a3a816149fe565b9050919050565b7f436c61696d2077696e646f772065787069726564000000000000000000000000600082015250565b6000614a77601483613f9e565b9150614a8282614a41565b602082019050919050565b60006020820190508181036000830152614aa681614a6a565b9050919050565b600081905092915050565b50565b6000614ac8600083614aad565b9150614ad382614ab8565b600082019050919050565b6000614ae982614abb565b9150819050919050565b7f5472616e73666572206661696c65640000000000000000000000000000000000600082015250565b6000614b29600f83613f9e565b9150614b3482614af3565b602082019050919050565b60006020820190508181036000830152614b5881614b1c565b9050919050565b7f4d7573742073656e64204d4f4e00000000000000000000000000000000000000600082015250565b6000614b95600d83613f9e565b9150614ba082614b5f565b602082019050919050565b60006020820190508181036000830152614bc481614b88565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000614c05826137e1565b9150614c10836137e1565b9250828202614c1e816137e1565b91508282048414831517614c3557614c346141cb565b5b5092915050565b7f57696e6e6572206e6f742073656c656374656400000000000000000000000000600082015250565b6000614c72601383613f9e565b9150614c7d82614c3c565b602082019050919050565b60006020820190508181036000830152614ca181614c65565b9050919050565b7f4e6f74207468652077696e6e6572000000000000000000000000000000000000600082015250565b6000614cde600e83613f9e565b9150614ce982614ca8565b602082019050919050565b60006020820190508181036000830152614d0d81614cd1565b9050919050565b7f43616e6e6f74206d61726b20636f6d706c657465640000000000000000000000600082015250565b6000614d4a601583613f9e565b9150614d5582614d14565b602082019050919050565b60006020820190508181036000830152614d7981614d3d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614dba826137e1565b9150614dc5836137e1565b925082614dd557614dd4614d80565b5b828204905092915050565b7f416d6f756e74206d757374206265203e20300000000000000000000000000000600082015250565b6000614e16601283613f9e565b9150614e2182614de0565b602082019050919050565b60006020820190508181036000830152614e4581614e09565b9050919050565b7f4578636565647320776974686472617761626c6520616d6f756e740000000000600082015250565b6000614e82601b83613f9e565b9150614e8d82614e4c565b602082019050919050565b60006020820190508181036000830152614eb181614e75565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600081519050614ef6816139fd565b92915050565b600060208284031215614f1257614f11613815565b5b6000614f2084828501614ee7565b91505092915050565b6000819050919050565b600063ffffffff82169050919050565b6000614f5e614f59614f5484614f29565b613db1565b614f33565b9050919050565b614f6e81614f43565b82525050565b6000604082019050614f8960008301856138a5565b614f966020830184614f65565b9392505050565b60006fffffffffffffffffffffffffffffffff82169050919050565b614fc281614f9d565b8114614fcd57600080fd5b50565b600081519050614fdf81614fb9565b92915050565b600060208284031215614ffb57614ffa613815565b5b600061500984828501614fd0565b91505092915050565b7f496e73756666696369656e742062616c616e636520666f722056524620666565600082015250565b6000615048602083613f9e565b915061505382615012565b602082019050919050565b600060208201905081810360008301526150778161503b565b9050919050565b6000819050919050565b615099615094826137e1565b61507e565b82525050565b60006150ab8285615088565b6020820191506150bb8284615088565b6020820191508190509392505050565b6150d481613b70565b82525050565b60006060820190506150ef60008301866138a5565b6150fc60208301856150cb565b6151096040830184614f65565b949350505050565b60008151905061512081613b44565b92915050565b60006020828403121561513c5761513b613815565b5b600061514a84828501615111565b91505092915050565b61515c81613b30565b82525050565b60006020820190506151776000830184615153565b92915050565b7f556e617574686f72697a65640000000000000000000000000000000000000000600082015250565b60006151b3600c83613f9e565b91506151be8261517d565b602082019050919050565b600060208201905081810360008301526151e2816151a6565b9050919050565b7f556e6b6e6f776e20726571756573740000000000000000000000000000000000600082015250565b600061521f600f83613f9e565b915061522a826151e9565b602082019050919050565b6000602082019050818103600083015261524e81615212565b9050919050565b6000615260826137e1565b915061526b836137e1565b92508261527b5761527a614d80565b5b82820690509291505056fea26469706673582212201348102d64481bb5e2cef4775050246d5d8e6a6ec68ff01308c8a53a241fdbe364736f6c634300081c0033

Block Transaction Gas Used Reward
view all blocks produced

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

Validator Index Block Amount
View All Withdrawals

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

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